U
    hâËdØ(  ã                   @   sž  d dl Z d dlmZmZmZmZmZmZmZm	Z	m
Z
 d dlZejdejfdejfgdd�Ze	eƒZej ZZej Ze
eeed�dd	„ ƒZe
eeed�d
d„ ƒZe
eeed�dd„ ƒZe
eeed�dd„ ƒZe
eeed�dd„ ƒZe
eeed�dd„ ƒZe
eeed�dd„ ƒZe
eeed�dd„ ƒZe de j ¡Ze de j ¡Ze
eeed�dd„ ƒZe
eeed�dd„ ƒZ e
eeed�dd„ ƒZ!d#dd „Z"d$d!d"„Z#dS )%é    N)	ÚconfigÚcudaÚfloat32Úfloat64Úuint32Úint64Úuint64Ú
from_dtypeÚjitÚs0Ús1T)Úalign)ZforceobjZloopliftZnopythonc                 C   sx   t |ƒ}t|ƒ}|tdƒ }||tdƒ? A tdƒ }||tdƒ? A tdƒ }||tdƒ? A }|| | d< || | d< d	S )
aÁ  Use SplitMix64 to generate an xoroshiro128p state from 64-bit seed.

    This ensures that manually set small seeds don't result in a predictable
    initial sequence from the random number generator.

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: uint64
    :param index: offset in states to update
    :type seed: int64
    :param seed: seed value to use when initializing state
    l   |”~åf»q	 é   l   ¹eÉ9´Âz é   l   ëb&ì&‚&	 é   r   r   N)r   r   r   )ÚstatesÚindexÚseedÚz© r   úJ/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/numba/cuda/random.pyÚinit_xoroshiro128p_state.   s    r   c                 C   s(   t | ƒ} t|ƒ}| |> | td| ƒ? B S )zLeft rotate x by k bits.é@   )r   r   )ÚxÚkr   r   r   ÚrotlH   s    r   c                 C   sx   t |ƒ}| | d }| | d }|| }||N }tt|tdƒƒƒ|A |tdƒ> A | | d< tt|tdƒƒƒ| | d< |S )zýReturn the next random uint64 and advance the RNG in states[index].

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: int64
    :param index: offset in states to update
    :rtype: uint64
    r   r   é7   é   é$   )r   r   r   r   )r   r   r   r   Úresultr   r   r   Úxoroshiro128p_nextP   s    
*r    c                 C   s¢   t |ƒ}tdƒtdƒf}tdƒ}tdƒ}tdƒD ]T}tdƒD ]F}|| tdƒt|ƒ> @ rx|| | d N }|| | d N }t| |ƒ q<q0|| | d< || | d< d	S )
zÛAdvance the RNG in ``states[index]`` by 2**64 steps.

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: int64
    :param index: offset in states to update
    l   ËzKWŸ`u l   "U.XC r   é   r   é   r   r   N)r   r   Úranger   r    )r   r   Zjumpr   r   ÚiÚbr   r   r   Úxoroshiro128p_jumpf   s    	r&   c                 C   s,   t | ƒ} | tdƒ? tdƒt dƒtdƒ>   S )z7Convert uint64 to float64 value in the range [0.0, 1.0)é   r"   é5   )r   r   r   ©r   r   r   r   Úuint64_to_unit_float64�   s    r*   c                 C   s   t | ƒ} tt| ƒƒS )z7Convert uint64 to float32 value in the range [0.0, 1.0))r   r   r*   r)   r   r   r   Úuint64_to_unit_float32ˆ   s    r+   c                 C   s   t |ƒ}tt| |ƒƒS )zþReturn a float32 in range [0.0, 1.0) and advance ``states[index]``.

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: int64
    :param index: offset in states to update
    :rtype: float32
    )r   r+   r    ©r   r   r   r   r   Úxoroshiro128p_uniform_float32�   s    
r-   c                 C   s   t |ƒ}tt| |ƒƒS )zþReturn a float64 in range [0.0, 1.0) and advance ``states[index]``.

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: int64
    :param index: offset in states to update
    :rtype: float64
    )r   r*   r    r,   r   r   r   Úxoroshiro128p_uniform_float64�   s    
r.   r!   c                 C   sH   t |ƒ}t| |ƒ}t| |ƒ}t tdƒ t |¡ ¡t t| ¡ }|S )a–  Return a normally distributed float32 and advance ``states[index]``.

    The return value is drawn from a Gaussian of mean=0 and sigma=1 using the
    Box-Muller transform.  This advances the RNG sequence by two steps.

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: int64
    :param index: offset in states to update
    :rtype: float32
    ç       @)r   r-   ÚmathÚsqrtr   ÚlogÚcosÚTWO_PI_FLOAT32©r   r   Úu1Úu2Zz0r   r   r   Úxoroshiro128p_normal_float32¯   s
    

(r8   c                 C   sH   t |ƒ}t| |ƒ}t| |ƒ}t tdƒ t |¡ ¡t t| ¡ }|S )a–  Return a normally distributed float32 and advance ``states[index]``.

    The return value is drawn from a Gaussian of mean=0 and sigma=1 using the
    Box-Muller transform.  This advances the RNG sequence by two steps.

    :type states: 1D array, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type index: int64
    :param index: offset in states to update
    :rtype: float64
    r/   )r   r-   r0   r1   r   r2   r3   ÚTWO_PI_FLOAT64r5   r   r   r   Úxoroshiro128p_normal_float64È   s
    

(r:   c                 C   st   | j d }t|ƒ}t|ƒ}|dkrpt| d|ƒ t|ƒD ]}t| dƒ q6td|ƒD ]}| |d  | |< t| |ƒ qPd S )Nr   r"   )Úshaper   r   r#   r&   )r   r   Úsubsequence_startÚnÚ_r$   r   r   r   Úinit_xoroshiro128p_states_cpuá   s    
r?   c                 C   s.   t j| jtd�}t|||ƒ | j||d� dS )aµ  Initialize RNG states on the GPU for parallel generators.

    This initializes the RNG states so that each state in the array corresponds
    subsequences in the separated by 2**64 steps from each other in the main
    sequence.  Therefore, as long no CUDA thread requests more than 2**64
    random numbers, all of the RNG states produced by this function are
    guaranteed to be independent.

    The subsequence_start parameter can be used to advance the first RNG state
    by a multiple of 2**64 steps.

    :type states: 1D DeviceNDArray, dtype=xoroshiro128p_dtype
    :param states: array of RNG states
    :type seed: uint64
    :param seed: starting seed for list of generators
    )r;   Údtype)ÚstreamN)ÚnpÚemptyr;   Úxoroshiro128p_dtyper?   Zcopy_to_device)r   r   r<   rA   Z
states_cpur   r   r   Úinit_xoroshiro128p_statesô   s    rE   c                 C   s"   t j| t|d�}t||||ƒ |S )a5  Returns a new device array initialized for n random number generators.

    This initializes the RNG states so that each state in the array corresponds
    subsequences in the separated by 2**64 steps from each other in the main
    sequence.  Therefore, as long no CUDA thread requests more than 2**64
    random numbers, all of the RNG states produced by this function are
    guaranteed to be independent.

    The subsequence_start parameter can be used to advance the first RNG state
    by a multiple of 2**64 steps.

    :type n: int
    :param n: number of RNG states to create
    :type seed: uint64
    :param seed: starting seed for list of generators
    :type subsequence_start: uint64
    :param subsequence_start:
    :type stream: CUDA stream
    :param stream: stream to run initialization kernel on
    )r@   rA   )r   Zdevice_arrayrD   rE   )r=   r   r<   rA   r   r   r   r   Úcreate_xoroshiro128p_states  s    rF   )r   r   )r   r   )$r0   Znumbar   r   r   r   r   r   r   r	   r
   ÚnumpyrB   r@   rD   Zxoroshiro128p_typeZENABLE_CUDASIMZ	_forceobjZ	_loopliftZ	_nopythonr   r   r    r&   r*   r+   r-   r.   Úpir4   r9   r8   r:   r?   rE   rF   r   r   r   r   Ú<module>   sD   ,ÿ












