U
    ©Ê¹j^+  ã                   @   sb  d dl mZmZ d dlZd dlm  mZ d dlm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 d d	lmZ d d
lmZmZmZ d dlmZmZ d dlmZmZ dZ ej! "e d¡Z#ej! "e dd¡Z$ej! "e dd¡Z%ej! "e dd¡Z&dd„ Z'd&dd„Z(ej)dœdd„Z*ej)dœdd„Z+dd„ Z,dd„ Z-d d!„ Z.d"d#„ Z/e.ƒ Z0e/ƒ Z1d$d%„ Z2dS )'é    )ÚOptionalÚTupleN)Ú_prims)ÚDispatchKey)Úautograd_not_implemented)ÚHigherOrderOperator)ÚCUDARngStateHelperÚmake_contiguous_strides_for)Úbackwards_not_supported)ÚFakeTensorMode)Údisable_proxy_modes_tracingÚProxyTorchDispatchModeÚtrack_tensor_tree)Ú_deviceÚ_dtype)Ú_get_current_dispatch_modeÚ_pop_mode_temporarilyÚrngprimsZDEFZIMPLZCompositeExplicitAutogradÚAutogradZMetac                 C   s&   t d| j› d| j› d| j› d�ƒ‚d S )Nz"You are trying to functionalize a z RNG operator but zE does not use Philox/counter-based RNG. Therefore, functionalizing a zo RNG operator is not supported. We are discussing the possibility of a Philox-based RNG implementation for CPU.)ÚRuntimeErrorÚtype)Údevice© r   úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/_prims/rng_prims.pyÚthrow_on_non_cuda"   s    ÿr   c           	      C   sˆ   t  |¡ t | |¡ t | |¡ ttjjj	| ƒ}|j
}|rB||_t | t|ƒ¡ ||fD ](}||_tjjj|_||_||_||_qZd S ©N)ÚrngprimZdefineÚrngprim_implÚimplÚrngprim_meta_implÚgetattrÚtorchZ_opsZopsr   ÚdefaultZ_tagsÚrngprim_autograd_implr
   Ú__doc__Z_prims_commonZRETURN_TYPEZNEWÚreturn_typeÚschemaÚ	impl_atenZprim_meta_impl)	Únamer&   r'   Ú	impl_metaÚdocÚtagsZprim_packetZprimÚpr   r   r   Úregister_rng_prim*   s    
r-   ©Úshapec                 C   s   t  tjdtjd�¡S )Nr   ©Údtype)r   Z
TensorLiker!   ZtensorÚint64r.   r   r   r   Úphilox_rand_offset_metaA   s    r3   c                 C   sŽ   d}| D ]}||9 }qt j|t jd�}d}d}d}t j t j ¡ ¡}|j| }|| d | }	t|	|j| ƒ}	|d ||	 |  d | }
|
S )Né   r0   é   é   )	r!   Zscalar_tensorr2   ÚcudaZget_device_propertiesZcurrent_deviceZmax_threads_per_multi_processorÚminZmulti_processor_count)r/   Znumel_scalarZdim_sizeZnumelÚ
block_sizeZunrollZcurand4_engine_callsZdevice_propertyZblocks_per_smZ	grid_sizeÚoffsetr   r   r   Úphilox_rand_offsetG   s    

þr;   c                  C   sz   d} d}t jt jt jtttdf  ttdœdd„}t jt jt jtttdf  ttdœdd„}t| |||d	t j	j
fd
� d S )NZphilox_randz†philox_rand(SymInt[] size, Tensor seed, Tensor offset, int[]? stride, Device? device=None, ScalarType? dtype=None) -> (Tensor, Tensor).)r/   Úseedr:   Ústrider   r1   c                 S   s6   |d kst ‚t| ƒ}tj| |||d�}t| ƒ}||fS )N)r/   Ústridesr1   r   )ÚAssertionErrorr	   r   Z
TensorMetar3   )r/   r<   r:   r=   r   r1   Úrandom_valuesr   r   r   Ú_philox_rand_metac   s    	   ÿz/register_philox_rand.<locals>._philox_rand_metac              	   S   st   |d kst ‚|jdkrg }n|g}|jdkr4t|ƒ‚tj |¡�" t ||¡ tj| ||d�}W 5 Q R X |t	| ƒfS )NÚcpur7   )r   r1   )
r?   r   r   r!   ÚrandomZfork_rngr   Zset_torch_state_tensorZrandr;   )r/   r<   r:   r=   r   r1   Údevicesr@   r   r   r   Ú_philox_randt   s    	

z*register_philox_rand.<locals>._philox_randz$Philox based stateless rand operator)r(   r&   r'   r)   r*   r+   )r!   ÚSizeÚTensorr   r   Úintr   r   r-   ÚTagZnondeterministic_seeded)r(   r&   rA   rE   r   r   r   Úregister_philox_rand_   s0    úúúrJ   c                 C   sl   |  d¡r.|  d¡}t|tƒr(t |¡}|jS dd„ | D ƒ}tdd„ |D ƒƒrRdS tdd„ |D ƒƒrhdS d S )	Nr   c                 S   s    h | ]}t |tjƒr|jj’qS r   )Ú
isinstancer!   rG   r   r   )Ú.0Úargr   r   r   Ú	<setcomp>�   s      zget_device.<locals>.<setcomp>c                 s   s   | ]}|d kV  qdS )r7   Nr   ©rL   Údevr   r   r   Ú	<genexpr>ž   s     zget_device.<locals>.<genexpr>r7   c                 s   s   | ]}|d kV  qdS )rB   Nr   rO   r   r   r   rQ       s     rB   )ÚgetrK   Ústrr!   r   r   Úany)ÚargsÚkwargsr   rD   r   r   r   Ú
get_device–   s    



rW   c                     sÐ   t dƒ‰ˆ tj¡ ˆ tj¡ ˆ tj¡ ˆ tj¡ ˆ tj¡ ˆ tj	¡t
ˆdd�ƒ ˆ tj¡dd„ ƒ‰ˆ tj¡dd„ ƒ‰ˆ tj¡‡‡fdd	„ƒ‰ ˆ t¡‡ fd
d„ƒ‰ˆ t¡‡‡fdd„ƒ} ˆS )NÚrun_and_save_rng_stateT©Zdeferred_errorc                 _   s   t j ¡ | ||ŽfS r   )r!   r7   Úget_rng_state©ÚoprU   rV   r   r   r   Ú	impl_cuda²   s    z5register_run_and_save_rng_state_op.<locals>.impl_cudac                 _   s   t  ¡ | ||ŽfS r   )r!   rZ   r[   r   r   r   Úimpl_cpu¶   s    z4register_run_and_save_rng_state_op.<locals>.impl_cpuc                    sB   ˆˆ dœ}t ||ƒ}||ks*td|› �ƒ‚|| }|| f|ž|ŽS ©N)r7   rB   zBackend not supported for ©rW   r?   )r\   rU   rV   Úimpl_mapr   r   ©r^   r]   r   r   Úimpl_backend_selectº   s
    

z?register_run_and_save_rng_state_op.<locals>.impl_backend_selectc                    s   ˆ | f|ž|ŽS r   r   r[   )rc   r   r   Úimpl_fake_tensor_modeÂ   s    zAregister_run_and_save_rng_state_op.<locals>.impl_fake_tensor_modec              
      s°   t ƒ }|d k	st‚tƒ �Ž}|jr†ˆ | f|ž|Ž}t |jj| f|˜¡}t |jj|¡}|j dˆ||¡}t	||d |jd�W  5 Q R £ S ˆ| f|ž|ŽW  5 Q R £ S W 5 Q R X d S ©NZcall_function)ZconstantÚtracer)
r   r?   r   Úenable_tracingÚpytreeÚtree_maprf   Úunwrap_proxyÚcreate_proxyr   )r\   rU   rV   ÚmodeÚoutÚ
proxy_argsÚproxy_kwargsÚ	out_proxy)rd   rX   r   r   Úimpl_proxy_dispatch_modeÇ   s(       ÿ   ÿzDregister_run_and_save_rng_state_op.<locals>.impl_proxy_dispatch_mode)r   Úfallthroughr   ÚADInplaceOrViewÚAutocastCPUÚAutocastCUDAÚPythonDispatcherÚPythonTLSSnapshotÚpy_implr   r   ÚCUDAÚCPUÚBackendSelectr   r   )rq   r   )rc   r^   r]   rd   rX   r   Ú"register_run_and_save_rng_state_op¥   s(    

ÿ




r|   c                     sÊ   t dƒ‰ˆ tj¡ ˆ tj¡ ˆ tj¡ ˆ tj¡ ˆ tj¡ ˆ tj	¡t
ˆdd�ƒ ˆ tj¡dd„ ƒ‰ˆ tj¡dd„ ƒ‰ ˆ t¡‡fdd	„ƒ} ˆ tj¡‡ ‡fd
d„ƒ}ˆ t¡dd„ ƒ}ˆS )NÚrun_with_rng_stateTrY   c                 _   s4   t j ¡ }t j |  ¡ ¡ |||Ž}t j |¡ |S r   )r!   r7   rZ   Úset_rng_staterB   ©Ú	rng_stater\   rU   rV   Zcurrent_staterm   r   r   r   r]   é   s
    

z1register_run_with_rng_state_op.<locals>.impl_cudac                 _   s*   t  ¡ }t  | ¡ |||Ž}t  |¡ |S r   )r!   rZ   r~   r   r   r   r   r^   ñ   s
    


z0register_run_with_rng_state_op.<locals>.impl_cpuc           	   
      sÈ   t ƒ }|d k	st‚tƒ �¦}|jrœtƒ � ˆ | |f|ž|Ž}W 5 Q R X t |jj| |f|˜¡}t |jj|¡}|j 	dˆ ||¡}t
||d |jd�W  5 Q R £ S ˆ | |f|ž|ŽW  5 Q R £ S W 5 Q R X d S re   )r   r?   r   rg   r   rh   ri   rf   rj   rk   r   )	r€   r\   rU   rV   rl   rm   rn   ro   rp   )r}   r   r   rq   ù   s0     
ÿ   ÿ   ÿz@register_run_with_rng_state_op.<locals>.impl_proxy_dispatch_modec                    sD   ˆˆ dœ}t ||ƒ}||ks*td|› �ƒ‚|| }|| |f|ž|ŽS r_   r`   )r€   r\   rU   rV   ra   r   r   rb   r   r   rc     s
    

z;register_run_with_rng_state_op.<locals>.impl_backend_selectc                 _   s
   |||ŽS r   r   )r€   r\   rU   rV   r   r   r   rd     s    z=register_run_with_rng_state_op.<locals>.impl_fake_tensor_mode)r   rr   r   rs   rt   ru   rw   rv   rx   r   r   ry   rz   r   r{   r   )rq   rc   rd   r   )r^   r]   r}   r   Úregister_run_with_rng_state_opÜ   s(    

ÿ





r�   c                   C   s
   t ƒ  d S r   )rJ   r   r   r   r   Úregister_rng_prims#  s    r‚   )N)3Útypingr   r   r!   Ztorch.utils._pytreeÚutilsZ_pytreerh   r   Ztorch._Cr   Ztorch._higher_order_ops.utilsr   Z
torch._opsr   Ztorch._prims_commonr   r	   Ztorch._prims_common.wrappersr
   Ztorch._subclasses.fake_tensorr   Z"torch.fx.experimental.proxy_tensorr   r   r   Ztorch.typesr   r   Ztorch.utils._python_dispatchr   r   Zrngprim_namespaceZlibraryÚLibraryr   r   r#   r   r   r-   rF   r3   r;   rJ   rW   r|   r�   rX   r}   r‚   r   r   r   r   Ú<module>   sD     ÿ
ÿÿ77C