U
    <c                    @   s~  d dl Z d dlZd dlZd dlmZ d dlZd dlZd dlmZ d dl	m
Z
 d dlmZ d dlm  mZ d dlm  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lmZmZmZmZ d d	l m!Z! d d
l"m#Z# ddddga$ddddga%e& a'ej(ddddZ)dd Z*dd Z+dIddZ,dd Z-dd Z.ddej/fddZ0ej1j2ej3dddZ4dd  Z5d!d" Z6d#d$ Z7ej1j2d%d& Z8ej1j2eej3 ej3ej3d'd(d)Z9d*d+ Z:d,d- Z;d.d/ Z<dJd1d2Z=d3d4 Z>d5d6 Z?G d7d8 d8eZ@G d9d: d:eZAG d;d< d<e!ZBG d=d> d>eBZCG d?d@ d@eBZDG dAdB dBeBZEG dCdD dDe!ZFG dEdF dFejGZHG dGdH dHe!ZIdS )K    N)Enum)	timedelta)Function)once_differentiable)RRef)IS_MACOSsandcastle_skip_if)	dist_initinitialize_pgwait_until_node_failureworker_name)RpcAgentTestFixture)skip_if_lt_x_gpuF   Trequires_gradc                 C   s   dt |< | t|< t|  d S NT)rpc_donectx_idsknown_context_idsadd)ctx_idrank_distance r   ^/tmp/pip-unpacked-wheel-gikjz4vx/torch/testing/_internal/distributed/rpc/dist_autograd_test.py_set_rpc_done.   s    r   c                 C   s   t |  std q d S )Ng?)r   timesleep)r   r   r   r   _check_rpc_done7   s    r   c                 C   s   t j| |dS )Nr   torchones)Zsizesr   r   r   r   _torch_ones<   s    r#   c                 C   sN   t | }||  }|jr8|js&t| }| }n
|jrBtt||S N)dist_autogradget_gradientslocal_valueZ	is_sparseAssertionErrorZto_denser!   equal)
context_idrrefgradgradsxr   r   r   _compare_owner_valueA   s    



r/   c                   C   s   t jdddS Nr   r   Tr   r    r   r   r   r   create_tensorM   s    r2   c                 C   sB   dddgdddgg}dddg}t j||d||d}| r>| }|S )	Nr         g	@gffffff@g333333@r1   r   dtype)r!   Zsparse_coo_tensorcoalesce)r7   r   r6   ivtensorr   r   r   build_sparse_tensorQ   s    
r;   )returnc                   C   s   t d S )Nr1   )r!   r"   Zrequires_grad_r   r   r   r   create_torchscript_tensorZ   s    r=   c                 C   s   t | |S r$   r!   r   t1t2r   r   r   	my_py_add_   s    rB   c                 C   s   | | S r$   r   )abr   r   r   my_scalar_addc   s    rE   c                 C   s   t |  |}|S r$   )r!   r   r'   )rref_t1rA   retr   r   r   my_rref_addg   s    rH   c                 C   s   t | |S r$   r>   r?   r   r   r   my_script_addl   s    rI   )ref_t1rA   r<   c                 C   s   |   }t||S r$   )to_herer!   r   )rJ   rA   r@   r   r   r   my_script_ref_addq   s    rL   c                 C   s   t j| t||fdS Nargs)rpcrpc_syncrH   )dstrF   rA   r   r   r   my_nested_rref_addw   s    rS   c                   C   s   t S r$   )requires_grad_tensorr   r   r   r   ret_requires_grad{   s    rU   c              	   C   sR   |d | }|dkr6t jt|t| ||||d fdS t jt|t| |fdS d S )Nr3   r   rN   )rP   rQ   r   my_py_nested_callrB   )r@   rA   rR   
world_sizeZhopsZnext_dstr   r   r   rV      s    rV   
   c              	   C   sl   t   }t }t   | | k r`|tkr`tD ]2}zt| W q* tk
rZ   || Y q*X q*q|tk}|S r$   )r   setr   r%   _retrieve_contextRuntimeErrorr   )Ztimeout_secondsstartZcontext_id_to_raisedr*   successr   r   r   _all_contexts_cleaned_up   s    r^   c              	   C   sx   t  f}tj|t| |fd}|r0tj|}n| }t ||g tj|t	||fd tj|t
dd W 5 Q R X d S NrN   r   )r%   contextrP   rQ   rH   r!   sparsesumbackwardr   r   rF   rA   Zps	rank_diffrb   r*   rG   lossr   r   r   _run_trainer   s    
rh   c              	   C   sx   t  f}tj|t| |fd}|r0tj|}n| }t ||g tj|t	||fd tj|t
dd W 5 Q R X d S r_   )r%   ra   rP   rQ   rL   r!   rb   rc   rd   r   r   re   r   r   r   _run_trainer_torchscript   s    
ri   c                   @   s,   e Zd ZdZedd Zeedd ZdS )SimulateBackwardErrorTc                 C   s   |S r$   r   ctxinputr   r   r   forward   s    zSimulateBackwardError.forwardc                 C   s   t jrtdn|S d S )NSimulate error on backward pass)rj   _simulate_error	Exceptionrk   r   r   r   rd      s    
zSimulateBackwardError.backwardN)__name__
__module____qualname__rp   staticmethodrn   r   rd   r   r   r   r   rj      s   
rj   c                   @   s   e Zd ZdZdZdZdZdS )ExecModer3   r4   r      N)rr   rs   rt   LOCALRPC_SYNCREMOTE	RPC_ASYNCr   r   r   r   rv      s   rv   c                   @   s   e Z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 Z
dd Zdd Zdd Zd9d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) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8S ):CommonDistAutogradTestc                 G   s   t j|kr8t|dkr0t|d tr0||d  S || S t j|krVtjt|||dS t j	|krxtj
t|||d S t j|krtjt|||d}| S td|d S )Nr3   r   rN   Unrecognized ExecMode {})rv   rx   len
isinstancelistry   rP   rQ   r   rz   remoterK   r{   	rpc_asyncwait
ValueErrorformat)selfrR   	exec_modemethodrO   Zfutr   r   r   _exec_func_with_dst   s    



z*CommonDistAutogradTest._exec_func_with_dstc                 G   s   | j |  ||f| S r$   )r   
_next_rank)r   r   r   rO   r   r   r   
_exec_func   s      z!CommonDistAutogradTest._exec_funcc                 C   sJ   t | dr2| jd | j | _| j| jkrD|  S n| jd | j | _| jS )Ndst_rankr3   )hasattrr   rW   rankr   r   r   r   r   r      s    

z!CommonDistAutogradTest._next_rankc                 C   s   t | d S r$   )r   )r   r   r   r   r   r      s    z&CommonDistAutogradTest._check_rpc_donec                 G   s<   |t jkr$tj| dd |D S | j|||f|  d S )Nc                 S   s   g | ]
}|j qS r   r,   ).0argr   r   r   
<listcomp>   s     z<CommonDistAutogradTest._verify_backwards.<locals>.<listcomp>)rv   rx   r!   autogradrd   _verify_backwards_remote)r   r   tensorsr*   local_gradsrO   r   r   r   _verify_backwards   s    
z(CommonDistAutogradTest._verify_backwardsc           	      G   s   t || t |}t|}d}td|D ]R}|| d k	rn| || | | || |||   |d7 }q,| || | q,| |t| d S )Nr   r3   )r%   rd   r&   r~   rangeassertInassertEqualassertNotIn)	r   r   r*   r   rO   r-   nargsZngradsr8   r   r   r   r      s    

z/CommonDistAutogradTest._verify_backwards_remotec              	   C   s  | j d | j }t| j| j | j t j}|r@t }t }n tjdddd}tj	dddd}t
j|krtjt||||fd}n6t
j|krtjt||||fd }ntd|tjt|t|dfd t }	| ||	  |	 }
| dt|
 |	 }| dt| | t|
 d t| d ||| | d tt d }	|	 }
| dt|
 | !t|
 d  t"#  W 5 Q R X | $t% t|}	W 5 Q R X | $t% t }	W 5 Q R X d S )Nr3   r   Tr   rN   r}   r   )&r   rW   r
   file_init_methodr%   ra   r;   r!   r"   zerosrv   ry   rP   rQ   r   rz   r   rK   r   r   r   _current_contextr   _context_id_send_functionsr~   _recv_functions _verify_graph_for_first_rpc_callr   valuesr   rZ   r   _verify_graph_for_rpc_call_execdistbarrierassertRaisesr[   )r   fnr   rb   r   r*   r@   rA   rG   rl   send_functionsrecv_functionsr   r   r   _test_graph  sZ    

    	
z"CommonDistAutogradTest._test_graphc              	   C   s  | j d | j }t| j| j | j t }|rHtdd}tdd}n tjdddd}tj	dddd}|d | j }t
j|krtjt|t|||| jdfd}n>t
j|krtjt|t|||| jdfd }ntd|t  dD ](}	tjt| j |	 | j t||	fd qt  t }
| ||
  |
 }| dt| |
 }| dt| | t|  d t|  d ||| t!t"d }
| #|
 t!t"d	 }
| #|
 t!t"d }
|
 }| dt| | $t|  d  t  W 5 Q R X d S )
Nr3   Tr   r   rN   r}   )r3   r4   r   r   r4   )%r   rW   r
   r   r%   ra   r;   r!   r"   r   rv   ry   rP   rQ   r   rV   rz   r   rK   r   r   r   r   r   r   r   r   r   r~   r   r   r   r   rZ   r   !_verify_graph_for_nested_rpc_callr   )r   r   rb   r   r*   r@   rA   Znest_dst_rankrG   rdrl   r   r   r   r   r   _test_graph_for_py_nested_callJ  sh    


	

z5CommonDistAutogradTest._test_graph_for_py_nested_callc              	   C   s  | j d | j }t| j| j | j t }|rHtdd}tdd}n tjdddd}tj	dddd}t
j|krtjt|t||| j d | j | j | jdfd}nPt
j|krtjt|t||| j d | j | j | jdfd }ntd|tjt| j d | j t|dfd t }| ||  | }	| dt|	 | }
| dt|
 | t|	 d t|
 d ||| | t|	 d  |  d t!t"d }| #| t$%  W 5 Q R X d S )	Nr3   Tr   r   r   rN   r}   r4   )&r   rW   r
   r   r%   ra   r;   r!   r"   r   rv   ry   rP   rQ   r   rV   rz   r   rK   r   r   r   r   r   r   r   r~   r   r   r   r   r   r   rZ   r   r   r   r   r   r   rb   r   r*   r@   rA   rG   rl   r   r   r   r   r   %_test_graph_for_py_nested_call_itself  sl    




z<CommonDistAutogradTest._test_graph_for_py_nested_call_itselfc              	   C   sL  t | j| j| j | jd | j }t }|rHtdd}tdd}n tjdddd}tj	dddd}t
j|krtjt|tj||fd}n8t
j|krtjt|tj||fd }ntd|tjt|t|dfd t }| }	| t|	d | }
| t|
d | d | dttd  t   W 5 Q R X d S )	Nr3   Fr   r   rN   r}   r   r   )!r
   r   r   rW   r%   ra   r;   r!   r"   r   rv   ry   rP   rQ   r   r   rz   r   rK   r   r   r   r   r   r   r~   r   r   ZassertNotEqualrZ   r   r   r   r   r   r   r   ,_test_no_graph_with_tensors_not_require_grad  sD    

  
    
zCCommonDistAutogradTest._test_no_graph_with_tensors_not_require_gradc              	   C   sn  t  Z}d}g }t|D ]>}|r8t|d dkd}ntjdd|d dkd}|| q|  }tj	|krt
jt|tj|fd}	n6tj|krt
jt|tj|fd }	ntd|| t||	 tt    d j}
d}tt|
D ]6}| d|
| d   | || |
| d j qt  }| }| t|d	 | ||h W 5 Q R X d S )
NrX   r4   r   r   r   rN   r}   torch::autograd::AccumulateGradr3   )r%   ra   r   r;   r!   r"   appendr   rv   ry   rP   rQ   r   stackrz   r   rK   r   r   r   r   r   r   r   next_functionsr~   namevariable_known_worker_ids)r   r   rb   r*   Znum_tensorsr   r8   r:   r   rG   
next_funcsidxrl   
worker_idsr   r   r   _test_rpc_complex_args  sN    
  
   z-CommonDistAutogradTest._test_rpc_complex_argsFc           	   	      s   t  j j j |r< jd  j }|d  j }|h}n fddt jD }t X}|D ]L}tjt	|||d tjt	|t
|dfd |rbtjt	|t
|dfd qbW 5 Q R X  t t| W 5 Q R X t  t } | d S )Nr3   c                    s   h | ]}| j kr|qS r   r   r   r   r   r   r   	<setcomp>G  s     
 zECommonDistAutogradTest.context_cleanup_test_helper.<locals>.<setcomp>rN   r4   r
   r   r   rW   r   r%   ra   rP   rQ   r   r   r   r[   rZ   r   r   r^   
assertTrue)	r   rpc_argsfuncnestedr   Znested_dst_rank	dst_ranksr*   r]   r   r   r   context_cleanup_test_helper:  s2    
  z2CommonDistAutogradTest.context_cleanup_test_helperc           	   	   C   s   t  }tjt|  tj||fd}|r:tj	|}n|	 }t j
||gdd | |j | |j t||}|rtj	|}n|	 }|
  | |j | |j |j}|j}t 
||g | ||j | ||j W 5 Q R X d S NrN   TZretain_graph)r%   ra   rP   rQ   r   r   r!   r   rb   rc   rd   ZassertIsNoner,   assertIsNotNoner   )	r   r@   rA   rb   r*   rg   Z
loss_localZt1_grad_beforeZt2_grad_beforer   r   r   _backward_no_grad_on_tensor_  s0    

z2CommonDistAutogradTest._backward_no_grad_on_tensorc              	   C   s  t ||}|rt j|}n| }|  t }|rNtj|t	dd}	ntj|t
dddid}	||krtj|t|	|fd}
ntj|t||	|fd}
|
 }|rt j|}n| }t||g t|}| || | || |j | tj|t||	|jfd W 5 Q R X d S )N)FTrN   )r1   r   TrO   kwargs)r!   r   rb   rc   rd   r%   ra   rP   r   r;   r#   rH   rS   rK   r&   r   r   r,   r   rQ   r/   )r   callee
rref_ownerr@   rA   r   rb   	local_retr*   rF   r+   rG   r-   r   r   r   _backward_rref  sP    
       

z%CommonDistAutogradTest._backward_rrefc                 C   s<  |rt dd}t dd}ntjddd}tjddd}t||}|rXtj|  n|   tj	t
| j|dd}dddg}g }	|D ]:}
|	tjt
| j|
 | j |||t
| j|
|fd q|D ]}
| |
 qd }|D ]<}
t|
 }t|}| }| || | || |j qtd d	 tj|	 d S )
NTr   r1   r   rN   r3   r4   r   r   )r;   r!   r"   r   r   rb   rc   rd   rP   r   r   r   r   r   rW   r   r   r%   r&   rK   r   r   r,   r   futuresZwait_all)r   Zcreate_ref_fnZ
trainer_fnrb   r@   rA   r   rF   Z
rank_diffsr   rf   Zaccumulate_grad_funcr   r-   Zlocal_t1r   r   r   _test_trainer_ps  sF    

	

z'CommonDistAutogradTest._test_trainer_psc                 C   s  t jt jt jfD ]}t }	| |tj||}
| |tj	||
}
| |tj
||
f}| |tj
||
f}|r| |tj	||}
| |tj	|
|
}
tj|
}n,| |tj||}
| |tj|
|
}
|
 }| ||g|	||||||	}|r|n|}W 5 Q R X qd S r$   )rv   rx   ry   rz   r%   ra   r   r!   r   mulr   rb   rc   Zbmmmatmulr   )r   r@   rA   t3t4t5r   rb   r   r*   vals1s2rg   rG   r   r   r   _backward_multiple_round_trips  s2    
        z5CommonDistAutogradTest._backward_multiple_round_tripsc              
   C   sp   d }t jt jfD ]Z}t H}| |tj||}|rBtj	|}n|	 }| 
||g||||}W 5 Q R X qd S r$   )rv   rx   rz   r%   ra   r   r!   r   rb   rc   r   )r   r@   rA   rb   r   r   r*   rg   r   r   r   _backward_different_dtypes  s    
     z1CommonDistAutogradTest._backward_different_dtypesc           	   
   C   sn   d }t jt jfD ]X}t F}| |t||}|r@tj	|}n|	 }| 
||g||||}W 5 Q R X qd S r$   )rv   rx   rz   r%   ra   r   rB   r!   rb   rc   r   )	r   r@   rA   rb   r   r   r*   rG   rg   r   r   r   _backward_simple_python_udf  s    
     z2CommonDistAutogradTest._backward_simple_python_udfc           
   
   C   s   d }t jt jt jt jfD ]d}t R}| |t||}|rHt	j
|}n| }| ||g||||}	|	rn|	n|}W 5 Q R X qd S r$   )rv   rx   ry   r{   rz   r%   ra   r   rI   r!   rb   rc   r   )
r   r@   rA   rb   r   r   r*   Zforward_retrg   rG   r   r   r   _backward_simple_script_call   s(    
     z3CommonDistAutogradTest._backward_simple_script_callc              	   C   sv   t  d}tjt|  tj|||  fd}|r@tj	
|}n|
 }t j||gdd t ||g W 5 Q R X d S r   )r%   ra   rP   rQ   r   r   DistAutogradTest&_test_nested_backward_accumulate_gradsr!   rb   rc   rd   )r   r@   rA   rb   r*   rG   rg   r   r   r   !_nested_backward_accumulate_grads3  s    

z8CommonDistAutogradTest._nested_backward_accumulate_gradsc           
   	   C   s   || }|| }|| }|| | | | }|r>t j|}n| }t j|g t }tjt	| 
 tj||| 
 fd}|rt j|}n| }t||g t|}	| |j|	|  | |j|	|  W 5 Q R X d S rM   )r!   rb   rc   r   rd   r%   ra   rP   rQ   r   r   r   _nested_python_udfr&   r   r,   )
r   r@   rA   rb   r   r   resrg   r*   r-   r   r   r   _backwards_nested_python_udfB  s*    


z3CommonDistAutogradTest._backwards_nested_python_udfc           	   
   C   s   t jt jfD ]}t }| |tj||}| || | |rNt	j
|}n| }t||g | |j | |j t|}| || | || | |||  W 5 Q R X qd S r$   )rv   ry   rz   r%   ra   r   r   _mixed_requires_grad_operatonr   r!   rb   rc   rd   r   r   assertFalser&   r   r   )	r   r@   rA   rb   r   r*   rG   rg   r-   r   r   r   _mixed_requires_grad]  s&    
   
z+CommonDistAutogradTest._mixed_requires_gradc              	   C   sp   t  ^}tjt|  tj||fd}|r:tj	|}n|	 }t
dD ]}t j||gdd qJW 5 Q R X d S )NrN     Tr   )r%   ra   rP   rQ   r   r   r!   r   rb   rc   r   rd   )r   r@   rA   rb   r*   rg   r8   r   r   r   _multiple_backwardp  s    

z)CommonDistAutogradTest._multiple_backwardc                 C   s   |j }| dt| | d|d d   | ||d d j | d|d d  | d|d d   | ||d d j | d|d d  | |j| d S )Nr4   r   r   r3   )r   r   r~   r   r   grad_fn)r   send_functionZrecv_functionr@   rA   rG   r   r   r   r   r     s    z7CommonDistAutogradTest._verify_graph_for_first_rpc_callc           
   
   C   s~   t jt jt jfD ]h}t V}| ||tj||}|rDtj	
|}	n|
 }	| ||	g||||}|rj|n|}W 5 Q R X qd S r$   )rv   rx   ry   rz   r%   ra   r   r!   r   rb   rc   r   )
r   rR   r@   rA   r   rb   r   r*   rG   rg   r   r   r   _backward_simple  s*    
         z'CommonDistAutogradTest._backward_simplec                 C   s   |j }| dt| |d d }| d|  |j }| dt| | d|d d   | d|d d   | |d d |d d  d S )Nr3   r   ZAddBackward0r4   -torch::distributed::autograd::RecvRpcBackward)r   r   r~   r   )r   r   r   Zadd_backward_fnr   r   r   r     s      z6CommonDistAutogradTest._verify_graph_for_rpc_call_execc                 C   s   |  }| dt| t| d j}| dt| | d|d d   | d|d d   | |d d |d d  t| d j}| dt| | d|d d   d S )Nr4   r   r   r3   )r   r   r~   r   r   r   r   )r   rl   r   r   r   r   r   r     s&       z8CommonDistAutogradTest._verify_graph_for_nested_rpc_callN)F)rr   rs   rt   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r|      s6   	<SJ*)
%$45r|   c                   @   s  e Zd Zedd Zedd Zedd Zedd Zed	d
 Zedd Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Zed5d6 Zed7d8 Zed9d: Z ed;d< Z!ed=d> Z"d?S )@TensorPipeAgentDistAutogradTestc                 C   s   |  tjtjd d S r   r   r!   r   rv   ry   r   r   r   r   "test_graph_for_builtin_call_sparse  s    zBTensorPipeAgentDistAutogradTest.test_graph_for_builtin_call_sparsec                 C   s   |  ttjd d S r   r   rB   rv   ry   r   r   r   r   !test_graph_for_python_call_sparse  s    zATensorPipeAgentDistAutogradTest.test_graph_for_python_call_sparsec                 C   s   |  tjtjd d S r   r   r!   r   rv   rz   r   r   r   r   )test_graph_for_builtin_remote_call_sparse  s    zITensorPipeAgentDistAutogradTest.test_graph_for_builtin_remote_call_sparsec                 C   s   |  ttjd d S r   r   rB   rv   rz   r   r   r   r   (test_graph_for_python_remote_call_sparse  s    zHTensorPipeAgentDistAutogradTest.test_graph_for_python_remote_call_sparsec                 C   s   |  tjd d S r   r   rv   ry   r   r   r   r   $test_graph_for_py_nested_call_sparse  s    zDTensorPipeAgentDistAutogradTest.test_graph_for_py_nested_call_sparsec                 C   s   |  tjd d S r   r   rv   rz   r   r   r   r   +test_graph_for_py_nested_remote_call_sparse	  s    zKTensorPipeAgentDistAutogradTest.test_graph_for_py_nested_remote_call_sparsec                 C   s   |  tjd d S r   r   rv   ry   r   r   r   r   +test_graph_for_py_nested_call_itself_sparse  s    zKTensorPipeAgentDistAutogradTest.test_graph_for_py_nested_call_itself_sparsec                 C   s   |  tjd d S r   r   rv   rz   r   r   r   r   2test_graph_for_py_nested_remote_call_itself_sparse  s    zRTensorPipeAgentDistAutogradTest.test_graph_for_py_nested_remote_call_itself_sparsec                 C   s   |  tjd d S r   r   rv   ry   r   r   r   r   2test_no_graph_with_tensors_not_require_grad_sparse  s    zRTensorPipeAgentDistAutogradTest.test_no_graph_with_tensors_not_require_grad_sparsec                 C   s   |  tjd d S r   r   rv   rz   r   r   r   r   9test_no_graph_with_tensors_not_require_grad_remote_sparse  s    zYTensorPipeAgentDistAutogradTest.test_no_graph_with_tensors_not_require_grad_remote_sparsec                 C   s   |  tjd d S r   r   rv   ry   r   r   r   r   test_rpc_complex_args_sparse  s    z<TensorPipeAgentDistAutogradTest.test_rpc_complex_args_sparsec                 C   s   |  tjd d S r   r   rv   rz   r   r   r   r   test_remote_complex_args_sparse!  s    z?TensorPipeAgentDistAutogradTest.test_remote_complex_args_sparsec                 C   s,   t dd}t dd}| j||ftjd d S )NTr   r   r   r;   r   r!   r   r   r@   rA   r   r   r   ,test_context_cleanup_tensor_with_grad_sparse%  s    

zLTensorPipeAgentDistAutogradTest.test_context_cleanup_tensor_with_grad_sparsec                 C   s"   t dd}| j||ftjd d S )NFr   r	  r
  r   r@   r   r   r   *test_context_cleanup_tensor_no_grad_sparse+  s    
zJTensorPipeAgentDistAutogradTest.test_context_cleanup_tensor_no_grad_sparsec                 C   sH   t dd}t dd}| jd | j }|||| jdf}| j|tdd d S )NTr   r3   r   r   r   r   )r;   r   rW   r   rV   r   r@   rA   r   rO   r   r   r   &test_context_cleanup_nested_rpc_sparse0  s    

  zFTensorPipeAgentDistAutogradTest.test_context_cleanup_nested_rpc_sparsec                 C   s   |  tddtddd d S NTr   )r   r;   r   r   r   r   &test_backward_no_grad_on_tensor_sparse:  s
    zFTensorPipeAgentDistAutogradTest.test_backward_no_grad_on_tensor_sparsec                 C   s&   |  |  tddtddd d d S r  )r   r   r;   r   r   r   r   test_backward_simple_sparseB  s    z;TensorPipeAgentDistAutogradTest.test_backward_simple_sparsec                 C   s$   |  | jtddtddd d d S r  )r   r   r;   r   r   r   r    test_backward_simple_self_sparseL  s    z@TensorPipeAgentDistAutogradTest.test_backward_simple_self_sparsec                 C   s6   | j dkr2d}|}| ||tddtddd d d S )Nr   worker0Tr   )r   r   r;   r   r   r   r   r   r   test_backward_rref_multi_sparseV  s    
z?TensorPipeAgentDistAutogradTest.test_backward_rref_multi_sparsec                 C   s4   t |  }|}| ||tddtddd d d S r  )r   r   r   r;   r  r   r   r   test_backward_rref_sparsed  s    z9TensorPipeAgentDistAutogradTest.test_backward_rref_sparsec                 C   sL   t | jd | j }t | jd | j }| ||tddtddd d d S )Nr3   r4   Tr   )r   r   rW   r   r;   r  r   r   r    test_backward_rref_nested_sparseq  s    z@TensorPipeAgentDistAutogradTest.test_backward_rref_nested_sparsec                 C   s   |  ttd d S r   )r   r;   rh   r   r   r   r   test_trainer_ps_sparse~  s
    z6TensorPipeAgentDistAutogradTest.test_trainer_ps_sparsec              	   C   s8   |  tddtddtddtddtddd d d S NTr   F)r   r;   r   r   r   r   )test_backward_multiple_round_trips_sparse  s    zITensorPipeAgentDistAutogradTest.test_backward_multiple_round_trips_sparsec                 C   s&   |  tdtjdtdtjdd d S )NTr5   )r   r;   r!   float32float64r   r   r   r   %test_backward_different_dtypes_sparse  s
    zETensorPipeAgentDistAutogradTest.test_backward_different_dtypes_sparsec                 C   s   |  tddtddd d S r  )r   r;   r   r   r   r   &test_backward_simple_python_udf_sparse  s
    zFTensorPipeAgentDistAutogradTest.test_backward_simple_python_udf_sparsec                 C   s   |  tddtddd d S r  )r   r;   r   r   r   r   'test_backward_simple_script_call_sparse  s
    zGTensorPipeAgentDistAutogradTest.test_backward_simple_script_call_sparsec                 C   s   |  tddtddd d S r  )r   r;   r   r   r   r   ,test_nested_backward_accumulate_grads_sparse  s
    zLTensorPipeAgentDistAutogradTest.test_nested_backward_accumulate_grads_sparsec                 C   s   |  tddtddd d S r  )r   r;   r   r   r   r   'test_backwards_nested_python_udf_sparse  s
    zGTensorPipeAgentDistAutogradTest.test_backwards_nested_python_udf_sparsec                 C   s   |  tddtddd d S r  )r   r;   r   r   r   r   test_mixed_requires_grad_sparse  s
    z?TensorPipeAgentDistAutogradTest.test_mixed_requires_grad_sparsec                 C   s   |  tddtddd d S r  )r   r;   r   r   r   r   test_multiple_backward_sparse  s
    z=TensorPipeAgentDistAutogradTest.test_multiple_backward_sparsec              
   C   s2  |   }tjt|tjjddddd}tjjddddd}tddd	d
d	dddg}tjddd}tdd	g}||||}tj	j
| gdd tj	
| g |jj}t r}	tjt|tj||||fd}
tj
|	|
 gdd t
|	|
 g tjt|tj||	fd}| || W 5 Q R X d S )N)   r'  rc   T)moderb   r   r'  r3   r4   rw      r   	      r   r   r   rN   )r   rP   r   r   r!   nnZEmbeddingBagZ
LongTensorrandr   rd   rc   weightr,   r%   ra   rQ   r   _call_remote_embedding	_get_gradr   )r   rR   Zremote_embeddingZlocal_embeddingrm   per_sample_weightsoffsetsZ	local_resZ
local_gradr*   r   Zremote_gradr   r   r   'test_embedding_bag_with_no_grad_tensors  s:    

zGTensorPipeAgentDistAutogradTest.test_embedding_bag_with_no_grad_tensorsN)#rr   rs   rt   r	   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r"  r#  r$  r%  r&  r3  r   r   r   r   r     s|   














	

	
	











r   c                   @   s  e Zd Zedd Zedd Zedd Zedd Zed	d
 Zedd Z	edd Z
edd Zedd Zedd Zedd Zedd Zdd Zedd Zedd Zedd  Zed!d" Zed#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Zed5d6 Zed7d8 Zed9d: Z ed;d< Z!ed=d> Z"ed?d@ Z#edAdB Z$edCdD Z%edEdF Z&edGdH Z'dIdJ Z(edKdL Z)edMdN Z*edOdPe+e,dQdRdS Z-edTdU Z.edVdW Z/edXdY Z0edZd[ Z1ed\d] Z2ed^d_ Z3ed`da Z4e5dbdc Z6eddde Z7e5dfdg Z8e5dhdi Z9edjdk Z:dOZ;edOdPe+e,dQdldm Z<e5dndo Z=edpdq Z>drZ?G dsdt dte@ZAedudv ZBeCdwdx ZDeCdydz ZEeCd{d| ZFed}d~ ZGG dd de@ZHedd ZIe5dd ZJedd ZKedd ZLe5dd ZMedd ZNedd ZOedOdPdd ZPedd ZQedd ZRedd ZSedd ZTedd ZUe5dd ZVedd ZWdrS )r   c              
   C   s   d}|  || jd>  t  g }tdD ]J}t 8}|  |t|  |  | j|d?  || W 5 Q R X q*|D ],}| 	t
d| t| W 5 Q R X qzd S )Nl    0      +Could not find autograd context with id: {})r   Z	worker_idr%   Z_get_max_idr   ra   rZ   r   r   assertRaisesRegexr[   r   )r   Zmax_auto_incrementZcontext_idsr8   r*   r   r   r   test_autograd_context  s(     
z&DistAutogradTest.test_autograd_contextc                 C   sD   t  2}| td t  }W 5 Q R X W 5 Q R X W 5 Q R X d S )Nz3Already have an autograd context id for this thread)r%   ra   r7  r[   )r   r*   r   r   r   test_nested_context  s    
 
z$DistAutogradTest.test_nested_contextc                 C   s   |  tjtjd d S NFr   r   r   r   r   test_graph_for_builtin_call  s    z,DistAutogradTest.test_graph_for_builtin_callc                 C   s   |  ttjd d S r:  r   r   r   r   r   test_graph_for_python_call  s    z+DistAutogradTest.test_graph_for_python_callc                 C   s   |  tjtjd d S r:  r   r   r   r   r   "test_graph_for_builtin_remote_call#  s    z3DistAutogradTest.test_graph_for_builtin_remote_callc                 C   s   |  ttjd d S r:  r   r   r   r   r   !test_graph_for_python_remote_call'  s    z2DistAutogradTest.test_graph_for_python_remote_callc                 C   s   |  tjd d S r:  r   r   r   r   r   test_graph_for_py_nested_call+  s    z.DistAutogradTest.test_graph_for_py_nested_callc                 C   s   |  tjd d S r:  r   r   r   r   r   $test_graph_for_py_nested_remote_call/  s    z5DistAutogradTest.test_graph_for_py_nested_remote_callc                 C   s   |  tjd d S r:  r   r   r   r   r   $test_graph_for_py_nested_call_itself3  s    z5DistAutogradTest.test_graph_for_py_nested_call_itselfc                 C   s   |  tjd d S r:  r   r   r   r   r   +test_graph_for_py_nested_remote_call_itself7  s    z<DistAutogradTest.test_graph_for_py_nested_remote_call_itselfc                 C   s   |  tjd d S r:  r  r   r   r   r   +test_no_graph_with_tensors_not_require_grad;  s    z<DistAutogradTest.test_no_graph_with_tensors_not_require_gradc                 C   s   |  tjd d S r:  r  r   r   r   r   2test_no_graph_with_tensors_not_require_grad_remote?  s    zCDistAutogradTest.test_no_graph_with_tensors_not_require_grad_remotec              	   C   s   t | j| j| j | jd | j }t }tj|krHt	t
|t}n.tj|krhtt
|t }ntd|t|| g tj	t
|t|dfd | d ttd }| dt| | t| | t||t  t  W 5 Q R X d S )Nr3   r}   rN   )r
   r   r   rW   r%   ra   rv   ry   rP   rQ   r   rU   rz   r   rK   r   r   rd   rc   r   r   r&   r   r   r~   r   rT   r!   Z	ones_liker   r   )r   r   r   r*   rG   r-   r   r   r   _test_grad_only_on_return_valueC  s.    


 
  
z0DistAutogradTest._test_grad_only_on_return_valuec                 C   s   |  tj d S r$   )rE  rv   ry   r   r   r   r   test_grad_only_on_return_value`  s    z/DistAutogradTest.test_grad_only_on_return_valuec                 C   s   |  tj d S r$   )rE  rv   rz   r   r   r   r   %test_grad_only_on_return_value_remoted  s    z6DistAutogradTest.test_grad_only_on_return_value_remotec                 C   s   |  tjd d S r:  r  r   r   r   r   test_rpc_complex_argsh  s    z&DistAutogradTest.test_rpc_complex_argsc                 C   s   |  tjd d S r:  r  r   r   r   r   test_remote_complex_argsl  s    z)DistAutogradTest.test_remote_complex_argsc                 C   s8   t jdddd}t jdddd}| j||ft jd d S Nr   Tr   r	  r!   r"   r   r   r   r  r   r   r   %test_context_cleanup_tensor_with_gradp  s    z6DistAutogradTest.test_context_cleanup_tensor_with_gradc                 C   s(   t jdddd}| j||ft jd d S )Nr   Fr   r	  )r!   r"   r   r   r  r   r   r   #test_context_cleanup_tensor_no_gradv  s    z4DistAutogradTest.test_context_cleanup_tensor_no_gradc                 C   s   | j dtd d S )N)r3   r3   r	  )r   rE   r   r   r   r   test_context_cleanup_no_tensors{  s    z0DistAutogradTest.test_context_cleanup_no_tensorsc                 C   sT   t jdddd}t jdddd}| jd | j }|||| jdf}| j|tdd d S )Nr   Tr   r3   r   r  )r!   r"   r   r   rW   r   rV   r  r   r   r   test_context_cleanup_nested_rpc  s      z0DistAutogradTest.test_context_cleanup_nested_rpcc           	   	      s   fddt  jD }t }tjdddd}tjdddd}|D ]6}tjt	|tj
||fd tjt	|t|dfd qFt }| } || d|_d|_|D ]6}tjt	|tj
||fd}tjt	|t|dfd q| } || W 5 Q R X d S )	Nc                    s   h | ]}| j kr|qS r   r   r   r   r   r   r     s     
 z<DistAutogradTest.test_worker_ids_recorded.<locals>.<setcomp>r   Fr   rN   r3   T)r   rW   r%   ra   r!   r"   r   rP   rQ   r   r   r   r   r   r   r   )	r   r   r*   r@   rA   r   rl   r   rG   r   r   r   test_worker_ids_recorded  s:    
      z)DistAutogradTest.test_worker_ids_recordedc           
   
      s   t  n}tjdddd}tjdddd}tjt|  tj||fd	 }tj
j }t ||g W 5 Q R X W 5 Q R X |j  fdd}|d}|d}|d	}	| |jd
 | |jd
 | |	j|j | |	j|j d S )Nr   Tr   rN   c                    s    fddD d S )Nc                    s   g | ]} |j kr|qS r   )r   )r   eventZpartial_keyr   r   r     s     
 zTDistAutogradTest.test_dist_autograd_profiling.<locals>.get_event.<locals>.<listcomp>r   r   rR  function_eventsrR  r   	get_event  s    z@DistAutogradTest.test_dist_autograd_profiling.<locals>.get_eventZSendRpcBackwardZRecvRpcBackwardz&torch::distributed::autograd::backwardr3   )r%   ra   r!   r-  rP   rQ   r   r   r   rc   r   ZprofilerZprofilerd   rT  r   countZassertGreaterZcpu_time_total)
r   r*   r@   rA   rg   prU  Z
send_eventZ
recv_eventZbackward_eventr   rS  r   test_dist_autograd_profiling  s    
""z-DistAutogradTest.test_dist_autograd_profilingc              
   C   sl   t  Z}tjdddd}tjdddd}| t$ tjt| 	 tj
||fd W 5 Q R X W 5 Q R X d S )Nr   Tr      rN   )r%   ra   r!   r-  r   r[   rP   rQ   r   r   r   )r   r*   r@   rA   r   r   r   test_error_in_context  s    

  z&DistAutogradTest.test_error_in_contextc                 C   s&   |  tjdddtjdddd d S Nr1   Tr   F)r   r!   r-  r   r   r   r   test_backward_no_grad_on_tensor  s
    z0DistAutogradTest.test_backward_no_grad_on_tensorc                 C   s.   |  |  tjdddtjdddd d d S r[  )r   r   r!   r-  r   r   r   r   test_backward_simple  s    z%DistAutogradTest.test_backward_simplec                 C   s,   |  | jtjdddtjdddd d d S r[  )r   r   r!   r-  r   r   r   r   test_backward_simple_self  s    z*DistAutogradTest.test_backward_simple_selfc              	   C   s<   t |  }|}| ||tjdddtjdddd d d S r[  )r   r   r   r!   r-  r  r   r   r   test_backward_rref  s    z#DistAutogradTest.test_backward_rrefc              	   C   s>   | j dkr:d}|}| ||tjdddtjdddd d d S )Nr   r  r1   Tr   F)r   r   r!   r-  r  r   r   r   test_backward_rref_multi  s    
z)DistAutogradTest.test_backward_rref_multic              	   C   sT   t | jd | j }t | jd | j }| ||tjdddtjdddd d d S )Nr3   r4   r1   Tr   F)r   r   rW   r   r!   r-  r  r   r   r   test_backward_rref_nested  s    z*DistAutogradTest.test_backward_rref_nestedc                 C   s   |  ttd d S r:  )r   r2   rh   r   r   r   r   test_trainer_ps  s
    z DistAutogradTest.test_trainer_psc                 C   s0   dd l m  m  m} d|_| ttd d S )Nr   TF)Ztorch.distributed.rpc.apidistributedrP   apiZ_ignore_rref_leakr   r=   ri   )r   rd  r   r   r   %test_trainer_ps_torchscript_functions  s    z6DistAutogradTest.test_trainer_ps_torchscript_functionsc              
   C   sD   |  tjdddtdtjdddtdtjdddd d d S r[  )r   r!   r-  r   r   r   r   "test_backward_multiple_round_trips%  s    z3DistAutogradTest.test_backward_multiple_round_tripsc                 C   s   d }t jddd}t d}t jddd}t d}tjtjtjfD ]r}t `}| |t j	||}| |t j
j|||f}| }	| ||	g|||||||	}
|
r|
n|}W 5 Q R X qDd S )N)rw   rY  Tr   )rY  r)  )r)     )rg  r*  )r!   r-  rv   rx   ry   rz   r%   ra   r   r   linalg	multi_dotrc   r   )r   r   r@   rA   r   r   r   r*   r   rg   rG   r   r   r   #test_backward_different_tensor_dims1  s,    


        z4DistAutogradTest.test_backward_different_tensor_dimsc                 C   s   d }t jddd}t jddd}t jddd}tjtjtjfD ]}t r}| |t j	|||f}| |t j
t |dddt |ddd}| }	| ||	g|||||}
|
r|
n|}W 5 Q R X q>d S )Nr1   Tr   r   r3   r4   )r!   r-  rv   rx   ry   rz   r%   ra   r   r   r   Znarrowrc   r   )r   r   r@   rA   r   r   r*   sr   rg   rG   r   r   r   test_backward_unused_tensorsD  s0    
      z-DistAutogradTest.test_backward_unused_tensorsc              
   C   s   d }t jddd}tjtjtjfD ]}t p}| |t j	|d}|d }|d }|d }| |t j
j|||f}	|	 }
| ||
g|||}|r|n|}W 5 Q R X q"d S )N)rX   r4   Tr   r4   r   rw   )r!   r-  rv   rx   ry   rz   r%   ra   r   splitrh  ri  rc   r   )r   r   tr   r*   Ztensor_listr@   rA   r   r   rg   rG   r   r   r   %test_backward_multiple_output_tensorsZ  s$    
    z6DistAutogradTest.test_backward_multiple_output_tensorsc              	   C   sp   t  ^}tjddd}tjddd}tjt|  tj||fd}t	||}t 
|| g W 5 Q R X d S )Nr1   Tr   rN   )r%   ra   r!   r-  rP   rQ   r   r   r   r   rd   rc   )r   r*   r@   rA   r   r   r   r   r   1_run_test_backward_unused_send_function_in_threadm  s    

  zBDistAutogradTest._run_test_backward_unused_send_function_in_threadc                 C   s8   t j| jd}d|_|  |d | |  d S )NtargetTrX   )	threadingThreadrp  daemonr\   joinr   is_alive)r   rn  r   r   r   "test_backward_unused_send_function}  s    
z3DistAutogradTest.test_backward_unused_send_functionc              
   C   s   t  }tjddd}tjddd}|| ||  }t|}tjt| 	 tj
||fd}tjt| 	 tj||fd}tjt| 	 tj||fd}tjt| 	 tj||fd}| td t || g W 5 Q R X W 5 Q R X d S )Nr1   Tr   rN   z5Error on Node [0-9]+: Simulate error on backward pass)r%   ra   r!   r-  rj   applyrP   rQ   r   r   r   r   r   divr7  r[   rd   rc   )r   r*   r@   rA   tmpr   r   r   r   r   #test_backward_autograd_engine_error  s<    


  
  
  
   z4DistAutogradTest.test_backward_autograd_engine_errorF)Zclean_shutdownzITest is flaky on MacOS since libuv error handling is not as robust as TCPc              
   C   s   t d t| j| j| j t }tj	ddd}tj	ddd}t j
t|  tj||fd}t  | jd dkr|  }t| jD ]}|d dkrt|| q| t| t|| g W 5 Q R X n W 5 Q R X d S )Nr)  r1   Tr   rN   r4   r   )rP   _set_rpc_timeoutr
   r   r   rW   r%   ra   r!   r-  rQ   r   r   r   r   r   get_shutdown_error_regexr   r   r7  r[   rd   rc   )r   r*   r@   rA   r   shutdown_error_regexr   r   r   r   test_backward_node_failure  s&    


  z+DistAutogradTest.test_backward_node_failurec              	   C   sr   t jddd}t jddd}d}| td|6 tjt|  t j	||fd}t
|| g W 5 Q R X d S )Nr1   Tr   d   r6  rN   )r!   r-  r7  r[   r   rP   rQ   r   r   r   r%   rd   rc   )r   r@   rA   r*   r   r   r   r   test_backward_without_context  s    
  z.DistAutogradTest.test_backward_without_contextc              	   C   s   | j }t }tjddd}tjddd}t||}t|| g t|}| 	dt
| | || | || | 	tdd||  | 	tdd||  W 5 Q R X d S )Nr1   Tr   r4   r   )r   r%   ra   r!   r-  r   rd   rc   r&   r   r~   r   r"   )r   r   r*   r@   rA   r   r-   r   r   r   test_backward_without_rpc  s    

z*DistAutogradTest.test_backward_without_rpcc              
   C   s"  t  }| td t |d  W 5 Q R X | td t d d  W 5 Q R X | td t |g  W 5 Q R X | td  tdd}t ||g W 5 Q R X | td$ tjdddd}t ||g W 5 Q R X | td" tjd	dd}t ||g W 5 Q R X W 5 Q R X d S )
Nzincompatible function argumentsz,No tensors provided for gradient computationzrequires_grad not set onr   z,is not a scalar, all roots need to be scalarTr   z'does not have a valid gradient functionr3   )r%   ra   r7  	TypeErrorrd   r[   r!   r-  )r   r*   rn  r   r   r   test_backward_invalid_args  s2       z+DistAutogradTest.test_backward_invalid_argsc           
   
   C   s   d }t jddd}t jddd}tjtjfD ]}t x}| |t j||	 }| |t j
||	 }| |t j|	 }| |t j||	 }	| |||||	g||||}W 5 Q R X q,d S r0   )r!   r-  rv   rx   ry   r%   ra   r   r   rc   r   cosrz  r   )
r   r   r@   rA   r   r*   Zr1Zr2Zr3Zr4r   r   r   test_backward_multiple_roots  s"    
 
    z-DistAutogradTest.test_backward_multiple_rootsc                 C   s.   |  tjddtjdtjddtjdd d S )Nr1   Tr5   F)r   r!   r-  r  r  r   r   r   r   test_backward_different_dtypes  s
    z/DistAutogradTest.test_backward_different_dtypesc                 C   s*   |  tjddddtjddddd d S Nr   Tr   F)r   r!   r-  r   r   r   r   test_backward_simple_python_udf#  s
    z0DistAutogradTest.test_backward_simple_python_udfc                 C   s*   |  tjddddtjddddd d S r  )r   r!   r-  r   r   r   r    test_backward_simple_script_call+  s
    z1DistAutogradTest.test_backward_simple_script_callc                 C   sF   t jj| |}t jj||}t jj||}t j| ||||gS r$   )r!   r,  
functionalZlinearrh  ri  )r@   rA   r   r   r   r   r   r   _complex_python_udf3  s    z$DistAutogradTest._complex_python_udfc              
   C   sz   d }t jddd}t jddd}tjtjfD ]H}t 6}| |tj	||}|
 }| ||g||||}W 5 Q R X q,d S r0   )r!   r-  rv   rx   rz   r%   ra   r   r   r  rc   r   )r   r   r@   rA   r   r*   rG   rg   r   r   r    test_backward_complex_python_udf:  s(    
        z1DistAutogradTest.test_backward_complex_python_udfc                 C   s&   | | }t |}tj| |||gS r$   )rj   ry  r!   rh  ri  )r@   rA   r   r   r   r   r   _python_udf_with_backward_errorK  s    
z0DistAutogradTest._python_udf_with_backward_errorc                 C   s<   | | } | | }t jt|tj| |fd}tj| ||gS rM   )rP   rQ   r   r   r  r!   rh  ri  )r@   rA   rR   r   r   r   r   _nested_rpc_call_backward_errorQ  s    z0DistAutogradTest._nested_rpc_call_backward_errorc              
   C   s   t jddd}t jddd}t T}tjt|  tj	|||  fd}| 
td t|| g W 5 Q R X W 5 Q R X d S )Nr1   Tr   rN   ro   )r!   r-  r%   ra   rP   rQ   r   r   r   r  r7  r[   rd   rc   )r   r@   rA   r*   rg   r   r   r   test_backward_python_udf_error\  s    

 z/DistAutogradTest.test_backward_python_udf_errorc              
   C   s
  t d t| j| j| j t }tj	ddd}tj	ddd}| 
 }t jt|t|||| jdfd}t  | jdkrW 5 Q R  d S tj }| jdkr|  }td| | t| t|| g W 5 Q R X |d	d
 n|d	gtdd W 5 Q R X d S )Nr)  r1   Tr   r3   rN   r4   r   Z0test_backward_node_failure_python_udf_rank0_doneTruerX   )seconds)rP   r}  r
   r   r   rW   r%   ra   r!   r-  r   rQ   r   rV   r   r   Zdistributed_c10dZ_get_default_storer~  r   r7  r[   rd   rc   rY   r   r   )r   r*   r@   rA   rR   r   storer  r   r   r   %test_backward_node_failure_python_udfm  s,    





z6DistAutogradTest.test_backward_node_failure_python_udfc                 C   s<   | | }| | }t jt|t||fd}| | | | | S rM   )rP   rQ   r   rB   )r@   rA   rR   r   r   r   r   r   r   r     s    z#DistAutogradTest._nested_python_udfc                 C   s*   |  tjddddtjddddd d S r  )r   r!   r-  r   r   r   r    test_backwards_nested_python_udf  s
    z1DistAutogradTest.test_backwards_nested_python_udfNc                   @   s(   e Zd Zedd Zeedd ZdS )zDistAutogradTest.MyBackwardFuncc                 C   s   |S r$   r   rk   r   r   r   rn     s    z'DistAutogradTest.MyBackwardFunc.forwardc                 C   s0   t jd k	stt  tt j t s,t|S r$   )r   '_test_clean_context_backward_context_idr(   r   r   r%   Z_release_contextr^   rk   r   r   r   rd     s    
z(DistAutogradTest.MyBackwardFunc.backwardNrr   rs   rt   ru   rn   r   rd   r   r   r   r   MyBackwardFunc  s
   
r  c              	   C   sF  t | j| j| j t }| }|t_t	d| jD ]<}|| jkr4|| j | j | j }t
jt|t||fd q4t  | | jd tt tjddd}t	ddD ]&}|  }t
jt|tj||fd}qtj|}| dt|  d}| td| t|| g W 5 Q R X t  t
jd	d
 t !d dS )a  
        This test simulates the situation where the 'backward' call might throw
        an exception locally which would lead to the autograd context being
        cleaned up if we're using the context manager. As a result, the autograd
        context might be cleaned up while some threads are still using the
        autograd context.

        It is fine for the 'backward' call to throw an exception in this test,
        but the process should not crash.
        r   rN   r3   r1   Tr   r  r6  F)ZgracefulN)"r
   r   r   rW   r%   Z_new_contextr   r   r  r   rP   rQ   r   r   r   r   r   r~   r   r!   r-  r   r   r  ry  r   r7  r[   r   rd   rc   shutdownsysexit)r   ra   r*   r8   r   r@   rR   r   r   r   "test_clean_context_during_backward  s:    
	z3DistAutogradTest.test_clean_context_during_backwardc                 C   s   |  }||||S r$   )r'   )clsembedding_rrefrm   r2  r1  	embeddingr   r   r   r/    s    z'DistAutogradTest._call_remote_embeddingc                 C   s   |  }t|}||j S r$   )r'   r%   r&   r.  )r  r  r*   r  Zgrad_mapr   r   r   r0    s    
zDistAutogradTest._get_gradc                 C   s   |j r|| S || S d S r$   r   )r  r@   rA   r   r   r   r   
  s    z.DistAutogradTest._mixed_requires_grad_operatonc                 C   s*   |  tjddddtjddddd d S r  )r   r!   r-  r   r   r   r   test_mixed_requires_grad  s
    z)DistAutogradTest.test_mixed_requires_gradc                   @   s(   e Zd Zedd Zeedd ZdS )z"DistAutogradTest.TestDebugInfoFuncc                 C   s   |S r$   r   rk   r   r   r   rn     s    z*DistAutogradTest.TestDebugInfoFunc.forwardc                 C   s8   t  }|d k	stt|d }|dkr0|dks4t|S )Nnum_current_backward_passesr3   rw   )r%   _get_debug_infor(   int)rl   rm   
debug_infoZbackward_passesr   r   r   rd     s
    z+DistAutogradTest.TestDebugInfoFunc.backwardNr  r   r   r   r   TestDebugInfoFunc  s
   
r  c           
   	   C   s  t | j| j| j tjddd}tjddd}t }d}i }|||< t| jD ]<}|| jkrTt	j
t|tj|| |fd||d < |d7 }qTtj|| ||d < |d7 }t| jD ]<}|| jkrt	j
t|tj|| |fd||d < |d7 }qt|||  g t }t|d }| |dko8|dk W 5 Q R X t| jd D ]2}	t	j
t| j|	 d | j t||	d fd qTt  t }|d k	st| dt|d	  | t|d
k | t  t }| dt|d  d S )Nr1   Tr   r   rN   r3   Znum_autograd_contextsrw   r  r4   )r
   r   r   rW   r!   r-  r%   ra   r   rP   rQ   r   r   r   r  ry  rd   rc   r  r  r   r   r   r   r(   r   r~   r^   )
r   r@   rA   r*   r8   r   r   r  Znum_autograd_contextr   r   r   r   test_debug_info+  sV    
  


  

"

z DistAutogradTest.test_debug_infoc               	   C   s   t jddd} t jddd}t p}tjdt j| |fd}tjdt j||fd}tjdt j||fd}tjdt j||fd}t	||
 g W 5 Q R X d S )Nr1   Tr   r  rN   )r!   r-  r%   ra   rP   rQ   r   r   r   rd   rc   )r@   rA   r*   r   r   r   t6r   r   r   _workload_threade  s    
z!DistAutogradTest._workload_threadc                 C   sl   t | j| j| j | jdkr`g }tdD ]$}tjtjd}|	  |
| q(|D ]}|  qRt  dS )z
        This test ensures async processing for distributed autograd works
        appropriately. This is achieved by spawning multiple threads and
        hammering a single node with a lot of backward() calls.
        r      rq  N)r
   r   r   rW   r   rs  rt  r   r  r\   r   rv  r   r   )r   threadsr8   rn  threadr   r   r   test_async_dist_autogradq  s    

z)DistAutogradTest.test_async_dist_autogradc              	   C   s  t jddd}t jddd}t }t ||}t jj| gdd t j| g tj	t
|  t j||fd}tj|| gdd t|| g t|}| dt| | || | || | |j||  | |j||  W 5 Q R X d S )Nr1   Tr   r   rN   r4   )r!   r-  r%   ra   r   r   rd   rc   rP   rQ   r   r   r&   r   r~   r   r,   r   r@   rA   r*   r   r-   r   r   r   test_backward_accumulate_grads  s&    

  
z/DistAutogradTest.test_backward_accumulate_gradsc                 C   s   t jt|tj| |fdS rM   )rP   rQ   r   r!   r   )r@   rA   r   r   r   r   r     s    z7DistAutogradTest._test_nested_backward_accumulate_gradsc                 C   s*   |  tjddddtjddddd d S r  )r   r!   r-  r   r   r   r   %test_nested_backward_accumulate_grads  s
    z6DistAutogradTest.test_nested_backward_accumulate_gradsc                 C   s*   |  tjddddtjddddd d S r  )r   r!   r-  r   r   r   r   test_multiple_backward  s
    z'DistAutogradTest.test_multiple_backwardc                 C   s   t | j| j| j tjddd}tjddd}t }tj	d
|  tj||fd }zxtdD ]j}|dk r| td tj||gdd	 W 5 Q R X qf|dkrtj||gdd	 qft  d
t_t  qfW 5 t  dt_X W 5 Q R X d S )Nr1   Tr   zworker{}rN   r  2   ro   r   F)r
   r   r   rW   r!   r-  r%   ra   rP   rQ   r   r   r   r  rc   r   r   rj   rp   r   r7  r[   rd   )r   r@   rA   r*   rg   r8   r   r   r   "test_multiple_backward_with_errors  s*    

z3DistAutogradTest.test_multiple_backward_with_errorsc              
   C   s   t jddd}|dd  t jddd}d }tjtjtjfD ]T}t B}| 	|t j
||}| }| ||g||||}|r|n|}W 5 Q R X q>d S )Nr1   Tr   c                 S   s   | d S Nr4   r   r   r   r   r   <lambda>      z=DistAutogradTest.test_backward_verify_hooks.<locals>.<lambda>)r!   r"   register_hookrv   rx   ry   rz   r%   ra   r   r   rc   r   )r   r@   rA   r   r   r*   rG   rg   r   r   r   test_backward_verify_hooks  s"    
     z+DistAutogradTest.test_backward_verify_hooksc           	   
      s  G  fdddt  G fdddt G dd dt }tjddd	d
}tjddd	d
}t \}t|| ||g t|}| || 	  j
k | || 	  j
k W 5 Q R X t L}t||d d g t|}j
}|| 	 }| ||k W 5 Q R X t }t| ||d d g t|} j
}|| 	 }|| 	 }| ||k | || 	  j
k | || 	  j
k W 5 Q R X dS )z6
        Similar to test in test_autograd.py.
        c                       s,   e Zd ZdZedd Ze fddZdS )z2DistAutogradTest.test_no_grad_copy.<locals>.MyFuncNc                 S   s   || S r$   r   rl   inp1Zinp2r   r   r   rn     s    z:DistAutogradTest.test_no_grad_copy.<locals>.MyFunc.forwardc                    s   |   _||fS r$   data_ptrstatic_grad_ptrrl   r,   MyFuncr   r   rd     s    
z;DistAutogradTest.test_no_grad_copy.<locals>.MyFunc.backwardrr   rs   rt   r  ru   rn   rd   r   r  r   r   r    s
   
r  c                       s,   e Zd ZdZedd Ze fddZdS )z<DistAutogradTest.test_no_grad_copy.<locals>.MyFuncSingleGradNc                 S   s   |S r$   r   rl   inpr   r   r   rn     s    zDDistAutogradTest.test_no_grad_copy.<locals>.MyFuncSingleGrad.forwardc                    s   |   _|S r$   r  r  MyFuncSingleGradr   r   rd     s    
zEDistAutogradTest.test_no_grad_copy.<locals>.MyFuncSingleGrad.backwardr  r   r  r   r   r    s
   
r  c                   @   s$   e Zd Zedd Zedd ZdS )z;DistAutogradTest.test_no_grad_copy.<locals>.NonContGradFuncc                 S   s   |  | _ tdgS )Ng      ?)sizer!   r:   )rl   r  r   r   r   rn   	  s    
zCDistAutogradTest.test_no_grad_copy.<locals>.NonContGradFunc.forwardc                 S   s   t d| jS Nr3   )r!   r"   expandr  r  r   r   r   rd   	  s    zDDistAutogradTest.test_no_grad_copy.<locals>.NonContGradFunc.backwardN)rr   rs   rt   ru   rn   rd   r   r   r   r   NonContGradFunc	  s   
r  r)  rY  Tr   r3   r   N)r   r!   randnr%   ra   rd   ry  r&   r   r  r  r   )	r   r  rC   rD   r*   r-   p_gp_ap_br   )r  r  r   test_no_grad_copy  s2    


"



z"DistAutogradTest.test_no_grad_copyc              
      s  G  fdddt  G fdddt tjdddd}tjdddd}td	d
ddddd
dg}tddg}dd lm  m} t } 	|}|j
|||dd }tj||gdd t|}	 j}
|	|   }| ||
k tdD ]}tj||gdd qW 5 Q R X t }	||}|j
|||dd }tj||gdd t|}	j}
|	|   }|	|   }| ||k | ||
k | ||
k tdD ]}tj||gdd qW 5 Q R X d S )Nc                       s,   e Zd ZdZedd Ze fddZdS )z9DistAutogradTest.test_no_grad_copy_sparse.<locals>.MyFuncNc                 S   s   |S r$   r   r  r   r   r   rn   2	  s    zADistAutogradTest.test_no_grad_copy_sparse.<locals>.MyFunc.forwardc                    s   |    _|S r$   )_valuesr  r  r  r  r   r   rd   6	  s    zBDistAutogradTest.test_no_grad_copy_sparse.<locals>.MyFunc.backwardr  r   r  r   r   r  /	  s
   
r  c                       s,   e Zd ZdZedd Ze fddZdS )zBDistAutogradTest.test_no_grad_copy_sparse.<locals>.NonContGradFuncNc                 S   s   || S r$   r   r  r   r   r   rn   >	  s    zJDistAutogradTest.test_no_grad_copy_sparse.<locals>.NonContGradFunc.forwardc                    sf   t dd}t jddt jd}|dd}|dd}t j||t ddg}| 	  _
||fS )Nr3   r   )r6   r+  rX   )r!   r-  r"   longr  rb   ZFloatTensorSizer  r  r  )rl   r,   r9   r8   nvniZngradr  r   r   rd   B	  s    zKDistAutogradTest.test_no_grad_copy_sparse.<locals>.NonContGradFunc.backwardr  r   r  r   r   r  ;	  s
   
r  rX   r   Tr   r3   r4   rw   r)  r*  r   rb   r   )r   r!   r  r:   torch.nn.functionalr,  r  r%   ra   ry  embedding_bagrc   rd   r&   r  r  r  r   r   r   )r   rC   rD   rm   r2  Fr*   
emb_matrixrg   r-   r  r  r8   r  r   )r  r  r   test_no_grad_copy_sparse,	  s<    




z)DistAutogradTest.test_no_grad_copy_sparsec              
      s   G  fdddt  tjdddd}tddd	d
d	dddg}tdd	g}dd lm  m} t ~} 	|}|j
|||dd }tj||gdd t|} j}	||   }
|  j |  j | |	|
k W 5 Q R X d S )Nc                       s4   e Zd ZdZdZdZedd Ze fddZdS )zHDistAutogradTest.test_grad_copy_sparse_indices_extra_ref.<locals>.MyFuncNc                 S   s   |S r$   r   r  r   r   r   rn   ~	  s    zPDistAutogradTest.test_grad_copy_sparse_indices_extra_ref.<locals>.MyFunc.forwardc                    s&   |    _|  _|   _|S r$   )r  r  r  Z_indicesstatic_grad_indices_refstatic_grad_values_refr  r  r   r   rd   	  s    

zQDistAutogradTest.test_grad_copy_sparse_indices_extra_ref.<locals>.MyFunc.backward)	rr   rs   rt   r  r  r  ru   rn   rd   r   r  r   r   r  y	  s   
r  rX   r   Tr   r3   r4   rw   r)  r*  r   r  r   )r   r!   r  r:   r  r,  r  r%   ra   ry  r  rc   rd   r&   r  r  r  r   r  r  r   )r   rC   rm   r2  r  r*   r  rg   r-   r  r  r   r  r   'test_grad_copy_sparse_indices_extra_refv	  s    


z8DistAutogradTest.test_grad_copy_sparse_indices_extra_refc           
   	      s   d _  fdd} fdd}tjdddd}|| }|jjd d }|| || |jjd	 d }|| t R}| }t	||g  
d
 j  t|}	 
d	t|	  ||	k W 5 Q R X d S )Nr   c                    s     j d7  _ | S r  hook_called_timesZoutput_gradsZinput_gradsr   r   r   post_hook_add_one	  s    z;DistAutogradTest.test_post_hooks.<locals>.post_hook_add_onec                    s     j d7  _ | S r  r  r  r   r   r   post_hook_add_two	  s    z;DistAutogradTest.test_post_hooks.<locals>.post_hook_add_tworX   Tr   r3   r)  )r  r!   r-  r   r   r  r%   ra   rc   rd   r   r&   r~   r   )
r   r  r  rn  rC   Zaccumulate_grad_0Zaccumulate_grad_1r*   rg   r-   r   r   r   test_post_hooks	  s"    




z DistAutogradTest.test_post_hooksc                 C   s   t d | | }d|_|S )Nr3   T)r   r   r   )r@   rA   r   r   r   r   	_slow_add	  s    
zDistAutogradTest._slow_addc              	   C   s   t d}t d}|| }d|_|   t| jd | j }tj	|t
j||fd}t >}|  }t||g | tj|t|||jfd W 5 Q R X d S )Nr1   Tr3   rN   )r!   r-  r   rc   rd   r   r   rW   rP   r   r   r  r%   ra   rK   r   rQ   r/   r,   )r   r@   rA   r   rR   r+   r*   rg   r   r   r   test_thread_local_context_id	  s"    



z-DistAutogradTest.test_thread_local_context_id)Xrr   rs   rt   r	   r8  r9  r;  r<  r=  r>  r?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rL  rM  rN  rO  rP  rX  rZ  r\  r]  r^  r_  r`  ra  rb  re  rf  rj  rl  ro  rp  rx  r|  r   r   r  r  r  r  r  r  r  r  ru   r  r  r  r  r  Z_backward_doner  r   r  r  r   r  r  classmethodr/  r0  r   r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r   r   r   r   r     s@  

	

















	




	
	











 












(


<




9








H
I
(

r   c                   @   sH   e Zd Zededd Zededd Zededd ZdS )	CudaDistAutogradTestr3   c              	   C   s   t jddddd}t jddddd}||    t ^}|| }t|| g t|}| dt| | |j	||  | |j	||  W 5 Q R X d S )Nr   Tcuda:0r   devicer4   )
r!   r-  rc   rd   r%   ra   r&   r   r~   r,   r  r   r   r   test_gpu_simple	  s    

z$CudaDistAutogradTest.test_gpu_simplec                 C   s   t jddddd}t jdddd}tdD ]}d |_d |_d }tjtjfD ]}t }| 	|t j
||}|d| }| 	|t j
| |}	|	d| }
| 	|t j
|
 |	}| || g||||}|r|n|}W 5 Q R X qJq*d S Nr   Tr  r  r   r   r!   r-  r   r,   rv   rx   ry   r%   ra   r   r   Zcudacpur   rc   )r   r@   rA   r8   r   r   r*   r   r   r   r  Zt7rG   r   r   r   test_gpu_to_cpu_continuation	  s,    
     z1CudaDistAutogradTest.test_gpu_to_cpu_continuationc                 C   s   t jddddd}t jdddd}tdD ]}d |_d |_d }tjtjfD ]}t p}| 	|t j
||}|d| }| 	|t j
| |}	|	d| }
| ||
 g||||}|r|n|}W 5 Q R X qJq*d S r  r  )r   r@   rA   r8   r   r   r*   r   r   r   r  rG   r   r   r   %test_gpu_to_cpu_continuation_gpu_root	
  s*    
     z:CudaDistAutogradTest.test_gpu_to_cpu_continuation_gpu_rootN)rr   rs   rt   r   r	   r  r  r  r   r   r   r   r  	  s   r  c                   @   s,   e Zd Zdd Zedd Zedd ZdS )FaultyAgentDistAutogradTestc              	      s   t  j j j  fddt jD }t <}|D ]0}tjt	|||d tjt	|t
|dfd q8W 5 Q R X  t t| W 5 Q R X t  t } | d S )Nc                    s   h | ]}| j kr|qS r   r   r   r   r   r   r   ,
  s     
 zJFaultyAgentDistAutogradTest.context_cleanup_test_helper.<locals>.<setcomp>rN   r3   r   )r   r   r   r   r*   r   r]   r   r   r   r   $
  s    
  z7FaultyAgentDistAutogradTest.context_cleanup_test_helperc                 C   s8   t jdddd}t jdddd}| j||ft jd d S rJ  rK  r  r   r   r   rL  @
  s    zAFaultyAgentDistAutogradTest.test_context_cleanup_tensor_with_gradc                 C   sL   |  | jtjjj |  | jjd |  | jjd |  t	| jj
d d S )Nr+  r   rw   )r   rpc_backendrP   Zbackend_registryZBackendTypeZFAULTY_TENSORPIPErpc_backend_optionsZnum_worker_threadsZnum_fail_sendsr~   Zmessages_to_failr   r   r   r   test_verify_backend_optionsF
  s    z7FaultyAgentDistAutogradTest.test_verify_backend_optionsN)rr   rs   rt   r   r	   rL  r  r   r   r   r   r  !
  s
   
r  c                       s,   e Zd Z fddZdd Zdd Z  ZS )WrapperModulec                    s   t    ||| _d S r$   )super__init__tomodel)r   r  r  	__class__r   r   r  O
  s    
zWrapperModule.__init__c                 G   s
   | j | S r$   )r  )r   rO   r   r   r   rn   S
  s    zWrapperModule.forwardc                    s"   t |  fdd| j D S )Nc                    s   g | ]} | qS r   r   r   rW  r-   r   r   r   X
  s     z+WrapperModule.gradients.<locals>.<listcomp>)r%   r&   r  
parameters)r   r   r   r  r   	gradientsV
  s    
zWrapperModule.gradients)rr   rs   rt   r  rn   r  __classcell__r   r   r  r   r  N
  s   r  c                   @   sd   e Zd Zeddd ZG dd dejjZG dd dejjZ	eddd	 Z
edd
d ZdS )TensorPipeCudaDistAutogradTestrw   c              	   C   s"  | j }t| jd | j }||| j| jd | j i tjt| j| j| j| j|d tj	d| jdd}tj	d| jdd}t
 }tj|tj||fd}t
|| g t
|}| td||  | td||  | |j|| j | |j|| j W 5 Q R X t  d S )Nr3   r   backendr   rW   r  rX   Tr  r   rN   )r  r   r   rW   set_device_maprP   init_rpcr  r!   r-  r%   ra   rQ   r   rd   rc   r&   r   r"   r  r  )r   optionsrR   r@   rA   r*   r   r-   r   r   r   test_device_maps_backward_pass]
  s*    

z=TensorPipeCudaDistAutogradTest.test_device_maps_backward_passc                       s$   e Zd Z fddZdd Z  ZS )z.TensorPipeCudaDistAutogradTest.MyRemoteComputec                    s   t    d S r$   )r  r  r   r  r   r   r  {
  s    z7TensorPipeCudaDistAutogradTest.MyRemoteCompute.__init__c                 C   s   |d }|S )N       @r   r   rm   r   r   r   rn   ~
  s    z6TensorPipeCudaDistAutogradTest.MyRemoteCompute.forwardrr   rs   rt   r  rn   r   r   r   r  r   MyRemoteComputez
  s   r  c                       s$   e Zd Z fddZdd Z  ZS )z-TensorPipeCudaDistAutogradTest.MyLocalComputec                    s   t    || _d S r$   )r  r  
next_stage)r   r  r  r   r   r  
  s    
z6TensorPipeCudaDistAutogradTest.MyLocalCompute.__init__c                 C   s   | j  |S r$   )r  rQ   rn   r
  r   r   r   rn   
  s    z5TensorPipeCudaDistAutogradTest.MyLocalCompute.forwardr  r   r   r  r   MyLocalCompute
  s   r  c              
   C   s  | j }t| jd | j }||| j| jd | j i tjt| j| j| j| j|d t|t	j
}t	|}tdD ]}tjddg| jdd}|d }t }| | }	|	  t D}
||}| | }	t|
|	g t|
}| |j||  W 5 Q R X qxt  d S )	Nr3   r  rX   r   i'  Tr  r	  )r  r   r   rW   r  rP   r  r  r   r  r  r  r   r!   r-  randomrc   rd   r%   ra   r&   r   r,   r  )r   r  rR   Zremote_computeZlocal_compute_rm   resultrrg   r*   r-   r   r   r   test_dist_autograd_sync_streams
  s2    


z>TensorPipeCudaDistAutogradTest.test_dist_autograd_sync_streamsc              	   C   s  | j }t| jD ]}|t|| j|i qtjt| j| j| j| j|d | jdkrdd t| jd D }dd |D }g }td| jD ]*}|	tj
t|t||d  |fd qtdd	d}tj| }||   t }	|D ]}
|
 |}qt|	| g g }|D ]}
|	|
 |	 q"tt|D ]F}d
d ||  D }t||  |D ]\}}| || qvqJW 5 Q R X t  d S )Nr  r   c                 S   s   g | ]}t d d qS )  )r,  ZLinear)r   r  r   r   r   r   
  s     zRTensorPipeCudaDistAutogradTest.test_gradients_synchronizations.<locals>.<listcomp>r3   c                 S   s   g | ]}| d qS r`   )r  )r   lr   r   r   r   
  s     rN   i  r  c                 S   s   g | ]
}|j qS r   r   r  r   r   r   r   
  s     )r  r   rW   r  r   r   rP   r  r  r   r   r  r!   r  r  r,  Z
Sequentialrc   rd   r%   ra   rQ   rn   r   r  r~   r  zipr   r   r  )r   r  Z	peer_rankZlayersZlocal_layersZremote_layersr   r.   Zlocal_modelr*   Zremote_layerZfutsr8   Zlocal_gradientsZg1Zg2r   r   r   test_gradients_synchronizations
  sF    


z>TensorPipeCudaDistAutogradTest.test_gradients_synchronizationsN)rr   rs   rt   r   r  r!   r,  Moduler  r  r  r  r   r   r   r   r  [
  s   

&r  )F)rX   )Jr  rs  r   enumr   r  r!   Ztorch.nnr,  datetimer   Ztorch.distributedrc  r   Ztorch.distributed.autogradr   r%   Ztorch.distributed.rpcrP   Z"torch.testing._internal.dist_utilsZtorch.autogradr   Ztorch.autograd.functionr   r   Z$torch.testing._internal.common_utilsr   r   r	   r
   r   r   Z>torch.testing._internal.distributed.rpc.rpc_agent_test_fixturer   Z*torch.testing._internal.common_distributedr   r   r   rY   r   r"   rT   r   r   r#   r/   r2   r  r;   ZjitscriptZTensorr=   rB   rE   rH   rI   rL   rS   rU   rV   r^   rh   ri   rj   rv   r|   r   r   r  r  r  r  r  r   r   r   r   <module>   s   		
	

      #           u?-