o
    8ήc'                     @   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
eeddd	 Ze
eedd
d Ze
eeddd Ze
eeddd Ze
eeddd Ze
eeddd Ze
eeddd Ze
eeddd Zede j Zede j Ze
eeddd Ze
eeddd Z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)forceobjloopliftc                 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   |~fq	    l   e9z    l   b&&&	    r   r   N)r   r   r   )statesindexseedz r   8/tmp/pip-target-vg8gfxp4/lib/python/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   rotlG   s   r   c                 C   sx   t |}| | d }| | d }|| }||N }tt|td|A |td> A | | d< tt|td| | d< |S )zReturn 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_nextO   s   
*r"   c                 C   s   t |}tdtdf}td}td}tdD ]*}tdD ]#}|| tdt|> @ r<|| | d N }|| | d N }t| | qq|| | d< || | d< d	S )
zAdvance 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   jumpr   r   ibr   r   r   xoroshiro128p_jumpe   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      t |}tt| |S )zReturn 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      
r1   c                 C   r/   )zReturn 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"   r0   r   r   r   xoroshiro128p_uniform_float64   r2   r3   r#   c                 C   H   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   r1   mathsqrtr   logcosTWO_PI_FLOAT32r   r   u1u2z0r   r   r   xoroshiro128p_normal_float32   
   

(r?   c                 C   r4   )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
    r5   )r   r1   r6   r7   r   r8   r9   TWO_PI_FLOAT64r;   r   r   r   xoroshiro128p_normal_float64   r@   rB   c                 C   sx   | j d }t|}t|}|dkr8t| d| t|D ]}t| d qtd|D ]}| |d  | |< t| | q(d S d S )Nr   r$   )shaper   r   r%   r)   )r   r   subsequence_startn_r'   r   r   r   init_xoroshiro128p_states_cpu   s   
rG   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
    )rC   dtype)streamN)npemptyrC   xoroshiro128p_dtyperG   copy_to_device)r   r   rD   rI   
states_cpur   r   r   init_xoroshiro128p_states   s   rO   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
    )rH   rI   )r   device_arrayrL   rO   )rE   r   rD   rI   r   r   r   r   create_xoroshiro128p_states  s   rQ   )r   r   )#r6   numbar   r   r   r   r   r   r   r	   r
   numpyrJ   rH   rL   xoroshiro128p_typeENABLE_CUDASIM	_forceobj	_loopliftr   r   r"   r)   r-   r.   r1   r3   pir:   rA   r?   rB   rG   rO   rQ   r   r   r   r   <module>   sD    ,























