o
    Td(                     @   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)forceobjlooplift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   |~fq	    l   e9z    l   b&&&	    r   r   N)r   r   r   )statesindexseedz r   d/home/ncw/WWW/www-new/content/articles/pi-bbp/venv/lib/python3.10/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 )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_nextP   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_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      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      
r2   c                 C   r0   )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#   r1   r   r   r   xoroshiro128p_uniform_float64   r3   r4   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   r2   mathsqrtr   logcosTWO_PI_FLOAT32r   r   u1u2z0r   r   r   xoroshiro128p_normal_float32   
   

(r@   c                 C   r5   )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
    r6   )r   r2   r7   r8   r   r9   r:   TWO_PI_FLOAT64r<   r   r   r   xoroshiro128p_normal_float64   rA   rC   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   
rH   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
    )rD   dtype)streamN)npemptyrD   xoroshiro128p_dtyperH   copy_to_device)r   r   rE   rJ   
states_cpur   r   r   init_xoroshiro128p_states   s   rP   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
    )rI   rJ   )r   device_arrayrM   rP   )rF   r   rE   rJ   r   r   r   r   create_xoroshiro128p_states  s   rR   )r   r   )$r7   numbar   r   r   r   r   r   r   r	   r
   numpyrK   rI   rM   xoroshiro128p_typeENABLE_CUDASIM	_forceobj	_looplift	_nopythonr   r   r#   r*   r.   r/   r2   r4   pir;   rB   r@   rC   rH   rP   rR   r   r   r   r   <module>   sF    ,












