o
    X۷ig                     @  s.  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dl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 d dlmZ d d	lmZ d dlZd dlZd
d ZedZdZdZG dd dZdddZ i a!ej"dd Z#dd Z$dd Z%dd Z&dS )    )annotationsN)LinAlgError)_core)cuda)device)_kernels)FeistelBijection)_utilc                 C  sD   t j| }t j|j}||_t j|}|tj| < || |S N)		importlibutil	find_spec
LazyLoaderloadermodule_from_specsysmodulesexec_module)namespecr   module r   L/home/ubuntu/vllm_env/lib/python3.10/site-packages/cupy/random/_generator.pylazy_import   s   

r   cupyxl    l    c                   @  s.  e Zd ZdZdddZdd Zdd Zdefd	d
Zde	fddZ
defddZdefddZddefddZdefddZddefddZdddZdddZedddd Zd!ddefd"d#Zd!ddefd$d%Zd!ddefd&d'Zdd(d)Zdd*d+d,efd-d.Zde	fd/d0Zd!ddefd1d2Zdefd3d4Zdefd5d6Zdefd7d8Zdd9d:Zdefd;d<Z d=d> Z!d?d@ Z"edAdBdCdDZ#dEdF Z$defdGdHZ%ddefdIdJZ&edKdLdMdNZ'edKdOdPdQZ(dRdS Z)dTdU Z*dVdW Z+edXdYdZd[Z,dd\d]Z-defd^d_Z.defd`daZ/defdbdcZ0defdddeZ1defdfdgZ2ddhdiZ3edjdBdkdlZ4defdmdnZ5edodBdpdqZ6d!ddefdrdsZ7defdtduZ8edvdwdxdyZ9defdzd{Z:defd|d}Z;de	fd~dZ<dddZ=dd Z>dd Z?dd Z@eddddZAd!ddefddZBdde	fddZCdS )RandomStateaV  Portable container of a pseudo-random number generator.

    An instance of this class holds the state of a random number generator. The
    state is available only on the device which has been current at the
    initialization of the instance.

    Functions of :mod:`cupy.random` use global instances of this class.
    Different instances are used for different devices. The global state for
    the current device can be obtained by the
    :func:`cupy.random.get_random_state` function.

    Args:
        seed (None or int): Seed of the random number generator. See the
            :meth:`~cupy.random.RandomState.seed` method for detail.
        method (int): Method of the random number generator. Following values
            are available::

               cupy.cuda.curand.CURAND_RNG_PSEUDO_DEFAULT
               cupy.cuda.curand.CURAND_RNG_PSEUDO_XORWOW
               cupy.cuda.curand.CURAND_RNG_PSEUDO_MRG32K3A
               cupy.cuda.curand.CURAND_RNG_PSEUDO_MTGP32
               cupy.cuda.curand.CURAND_RNG_PSEUDO_MT19937
               cupy.cuda.curand.CURAND_RNG_PSEUDO_PHILOX4_32_10

    Nc                 C  sX   ddl m} |d u r|j}t | _||| _t	| |j
| j| _|| _| | d S )Nr   curand)cupy_backends.cuda.libsr   CURAND_RNG_PSEUDO_DEFAULT	threadingLock_lockcreateGenerator
_generatorweakreffinalizedestroyGenerator
_finalizermethodseed)selfr*   r)   r   r   r   r   __init__J   s   

zRandomState.__init__c                 C  s@   | j  | j}|| t | _W d    |S 1 sw   Y  |S r
   )r"   _rk_seed_UINT64_MAX)r+   sizerk_seedr   r   r   	_get_seedZ   s   
zRandomState._get_seedc                 G  s   t |}t j|}|d dkr<tj||d}| j || j|jj	|j
g|R   W d    |S 1 s5w   Y  |S tj|d f|d}| j || j|jj	|j
g|R   W d    n1 sbw   Y  |d | |S )N   r   dtype   )r   get_sizeinternalprodcupyemptyr"   r$   dataptrr/   reshape)r+   funcr/   r4   argselement_sizeoutr   r   r   _generate_normal`   s   

zRandomState._generate_normalc                 C  Z   t |t |}}|du rt ||j}t j||d}| |j}t|||| |S )zReturns an array of samples drawn from the beta distribution.

        .. seealso::
            - :func:`cupy.random.beta` for full documentation
            - :meth:`numpy.random.RandomState.beta`
        Nshaper4   )	r9   asarray	broadcastrE   r:   r1   r/   r   beta_kernel)r+   abr/   r4   yr0   r   r   r   betau      zRandomState.betac                 C  rC   )zReturns an array of samples drawn from the binomial distribution.

        .. seealso::
            - :func:`cupy.random.binomial` for full documentation
            - :meth:`numpy.random.RandomState.binomial`
        NrD   )	r9   rF   rG   rE   r:   r1   r/   r   binomial_kernel)r+   npr/   r4   rK   r0   r   r   r   binomial   rM   zRandomState.binomialc                 C  D   t |}|du r|j}t j||d}| |j}t||| |S )zReturns an array of samples drawn from the chi-square distribution.

        .. seealso::
            - :func:`cupy.random.chisquare` for full documentation
            - :meth:`numpy.random.RandomState.chisquare`
        NrD   )r9   rF   rE   r:   r1   r/   r   chisquare_kernelr+   dfr/   r4   rK   r0   r   r   r   	chisquare      
zRandomState.chisquarec                 C  s   t |}|du r|j}nt|tt jfr|f|j }n||j7 }t j||d}| |j}t	
||| ||jddd }|S )zReturns an array of samples drawn from the dirichlet distribution.

        .. seealso::
            - :func:`cupy.random.dirichlet` for full documentation
            - :meth:`numpy.random.RandomState.dirichlet`
        NrD   T)axiskeepdims)r9   rF   rE   
isinstanceintintegerr:   r1   r/   r   standard_gamma_kernelsum)r+   alphar/   r4   rK   r0   r   r   r   	dirichlet   s   

zRandomState.dirichlet      ?c                 C  sF   t ||}|dk  rtd|du r|j}| ||}||9 }|S )a.  Returns an array of samples drawn from a exponential distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.exponential` for full documentation
            - :meth:`numpy.random.RandomState.exponential`
        r   	scale < 0N)r9   rF   any
ValueErrorrE   standard_exponentialr+   scaler/   r4   xr   r   r   exponential   s   zRandomState.exponentialc                 C  rC   )zReturns an array of samples drawn from the f distribution.

        .. seealso::
            - :func:`cupy.random.f` for full documentation
            - :meth:`numpy.random.RandomState.f`
        NrD   )	r9   rF   rG   rE   r:   r1   r/   r   f_kernel)r+   dfnumdfdenr/   r4   rK   r0   r   r   r   f   rM   zRandomState.fc                 C  s`   t |t |}}|du rt ||j}t j||d}| |j}t||| ||9 }|S )zReturns an array of samples drawn from a gamma distribution.

        .. seealso::
            - :func:`cupy.random.gamma` for full documentation
            - :meth:`numpy.random.RandomState.gamma`
        NrD   )	r9   rF   rG   rE   r:   r1   r/   r   r^   )r+   rE   rh   r/   r4   rK   r0   r   r   r   gamma   s   zRandomState.gammalc                 C  rR   )zReturns an array of samples drawn from the geometric distribution.

        .. seealso::
            - :func:`cupy.random.geometric` for full documentation
            - :meth:`numpy.random.RandomState.geometric`
        NrD   )r9   rF   rE   r:   r1   r/   r   geometric_kernelr+   rP   r/   r4   rK   r0   r   r   r   	geometric   rW   zRandomState.geometricc                 C  sj   t |t |t |}}}|du rt |||j}t j||d}| |j}t||||| |S )zReturns an array of samples drawn from the hypergeometric distribution.

        .. seealso::
            - :func:`cupy.random.hypergeometric` for full documentation
            - :meth:`numpy.random.RandomState.hypergeometric`
        NrD   )	r9   rF   rG   rE   r:   r1   r/   r   hypergeometric_kernel)r+   ngoodnbadnsampler/   r4   rK   r0   r   r   r   hypergeometric   s   zRandomState.hypergeometriczT x, T loc, T scalezT yz>y = loc + scale * ((x <= 0.5) ? log(x + x): -log(x + x - 1.0))cupy_laplace_kernel        c                 C  sN   t ||}t ||}|du rt ||j}| ||}t|||| |S )zReturns an array of samples drawn from the laplace distribution.

        .. seealso::
            - :func:`cupy.random.laplace` for full documentation
            - :meth:`numpy.random.RandomState.laplace`
        N)r9   rF   rG   rE   _random_sample_rawr   _laplace_kernelr+   locrh   r/   r4   ri   r   r   r   laplace  s   zRandomState.laplacec                 C  s   t |t |}}|du rt ||j}t j||d}| |j}t|| d| | }t j	||d t j
|||d t j|||d |S )zReturns an array of samples drawn from the logistic distribution.

        .. seealso::
            - :func:`cupy.random.logistic` for full documentation
            - :meth:`numpy.random.RandomState.logistic`
        NrD   rb   rA   )r9   rF   rG   rE   r:   r1   r/   r   open_uniform_kernellogmultiplyadd)r+   r~   rh   r/   r4   ri   r0   r   r   r   logistic  s   zRandomState.logisticc                 C  s   ddl m} tdd ||fD r"| ||||}tj||d |S |du r(d}t|}|jdkr5|j}n|j	}| 
|||||S )	zReturns an array of samples drawn from a log normal distribution.

        .. seealso::
            - :func:`cupy.random.lognormal` for full documentation
            - :meth:`numpy.random.RandomState.lognormal`

        r   r   c                 s  s    | ]	}t |tjV  qd S r
   )r[   r9   ndarray).0argr   r   r   	<genexpr>9  s    z(RandomState.lognormal.<locals>.<genexpr>r   Nr   rn   )r   r   rd   normalr9   exp_check_and_get_dtypechargenerateLogNormalgenerateLogNormalDoublerB   )r+   meansigmar/   r4   r   ri   r>   r   r   r   	lognormal/  s   
zRandomState.lognormalc                 C  sp   t |}t |dkrtdt |dkrtd|du r"|j}t j||d}| |j}t	||| |S )a*  Returns an array of samples drawn from a log series distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.logseries` for full documentation
            - :meth:`numpy.random.RandomState.logseries`

        r   zp <= 0.0r5   zp >= 1.0NrD   )
r9   rF   rd   re   rE   r:   r1   r/   r   logseries_kernelrr   r   r   r   	logseriesF  s   
zRandomState.logseriesignoreg:0yE>choleskyc                 C  s>  t d tj||d}tj||d}|du rg }nt|ttjfr&|g}n|}t|jdkr3t	dt|jdksD|jd |jd krHt	d|jd |jd krVt	d	t
|dd }	|	|jd  |d
vrnt	d|dkr~|dkr~|dkr~t	d|dkrtjdd ztj|}
W nv ty   tjdd] |dkr|dkrtj|\}}t|| k  }|dkrtj|\}}}tjt|j| ||||d}|tt| }
|stdt ntdt tj|}
W d   n	1 sw   Y  Y nw W d   n	1 sw   Y  nbtj|dS z>|dkr.tj|}
n0|dkrFtj|\}}|tt| }
n|dkr^tj|\}}}|tt| }
W n tyk   tdw W d   n	1 sww   Y  | j|	|dd|jd }t|
|j}|j}||7 }t|	|_|S )ae  Returns an array of samples drawn from the multivariate normal
        distribution.

        .. warning::
            This function calls one or more cuSOLVER routine(s) which may yield
            invalid results if input conditions are not met.
            To detect these invalid results, you can set the `linalg`
            configuration to a value that is not `ignore` in
            :func:`cupyx.errstate` or :func:`cupyx.seterr`.

        .. seealso::
            - :func:`cupy.random.multivariate_normal` for full documentation
            - :meth:`numpy.random.RandomState.multivariate_normal`
        z+cupy.random.RandomState.multivariate_normalr3   Nr5   zmean must be 1 dimensionalr2   r   z$cov must be 2 dimensional and squarez"mean and cov must have same length>   svdeighr   z1method must be one of {'eigh', 'svd', 'cholesky'}r   warnraisez3check_valid must equal 'warn', 'raise', or 'ignore')linalgr   r   r   )rtolatolz?covariance is not positive-semidefinite, output may be invalid.z=covariance is not positive-semidefinite, output *is* invalid.z_Matrix is not positive definite; if matrix is positive-semidefinite, set'check_valid' to 'warn'rX   )r	   experimentalr9   rF   r[   r\   r]   lenrE   re   listappendr   errstater   r   r   r   rd   r   allclosedotTsqrtabswarningsr   RuntimeWarningstandard_normalr=   tuple)r+   r   covr/   check_validtolr)   r4   rE   final_shapedecompsupsdvhri   r   r   r   multivariate_normal^  s   
"




zRandomState.multivariate_normalc                 C  sz   t |}t |}t |dkrtdt |dk r tdt |dkr+td| |d| | |}| j||dS )aB  Returns an array of samples drawn from the negative binomial distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.negative_binomial` for full documentation
            - :meth:`numpy.random.RandomState.negative_binomial`
        r   zn <= 0zp < 0r5   zp > 1r3   )r9   rF   rd   re   ro   poisson)r+   rO   rP   r/   r4   rK   r   r   r   negative_binomial  s   

zRandomState.negative_binomialc                 C  s   ddl m} t|}|du rt||j}|jdkr|j}n|j}t	|tj
rB| |||dd}tj|||d tj|||d |S t	|tj
r[| |||d|}tj|||d |S | |||||}|S )zReturns an array of normally distributed samples.

        .. seealso::
            - :func:`cupy.random.normal` for full documentation
            - :meth:`numpy.random.RandomState.normal`

        r   r   Nrn   rz   rb   r   )r   r   r   r9   rG   rE   r   generateNormalgenerateNormalDoubler[   r   rB   r   r   )r+   r~   rh   r/   r4   r   r>   ri   r   r   r   r     s$   
zRandomState.normalc                 C  sN   t |}|du r|j}| ||}t j||d t j| | |d |d S )zReturns an array of samples drawn from the pareto II distribution.

        .. seealso::
            - :func:`cupy.random.pareto` for full documentation
            - :meth:`numpy.random.RandomState.pareto`
        Nr   r5   )r9   rF   rE   r{   r   r   r+   rI   r/   r4   ri   r   r   r   pareto  s   
zRandomState.paretoc                 C  s   t |t |}}t |dkrtdt |dk r!td|du r,t ||j}t j||d}| |j}t	
|||| |S )aT  Returns an array of samples drawn from the noncentral chi-square
        distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.noncentral_chisquare` for full documentation
            - :meth:`numpy.random.RandomState.noncentral_chisquare`
        r   zdf <= 0nonc < 0NrD   )r9   rF   rd   re   rG   rE   r:   r1   r/   r   noncentral_chisquare_kernel)r+   rU   noncr/   r4   rK   r0   r   r   r   noncentral_chisquare  s   z RandomState.noncentral_chisquarec                 C  s   t |t |t |}}}t |dkrtdt |dkr'tdt |dk r2td|du r>t |||j}t j||d}| |j}t	
||||| |S )a3  Returns an array of samples drawn from the noncentral F distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.noncentral_f` for full documentation
            - :meth:`numpy.random.RandomState.noncentral_f`
        r   z
dfnum <= 0z
dfden <= 0r   NrD   )r9   rF   rd   re   rG   rE   r:   r1   r/   r   noncentral_f_kernel)r+   rl   rm   r   r/   r4   rK   r0   r   r   r   noncentral_f  s   zRandomState.noncentral_fc                 C  rR   )zReturns an array of samples drawn from the poisson distribution.

        .. seealso::
            - :func:`cupy.random.poisson` for full documentation
            - :meth:`numpy.random.RandomState.poisson`
        NrD   )r9   rF   rE   r:   r1   r/   r   poisson_kernel)r+   lamr/   r4   rK   r0   r   r   r   r   1  rW   zRandomState.poissonc                 C  sv   t |}t |dk rtd|du r|j}| j||d}t j| |d t jd| |d t j|d| |d |S )a  Returns an array of samples drawn from the power distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.power` for full documentation
            - :meth:`numpy.random.RandomState.power`
        r   a < 0Nr/   r4   r   r5   rb   )	r9   rF   rd   re   rE   rf   r   r   powerr   r   r   r   r   @  s   
zRandomState.powerc                 O  4   | dt}|rtdd|  | j||dS )zReturns uniform random values over the interval ``[0, 1)``.

        .. seealso::
            - :func:`cupy.random.rand` for full documentation
            - :meth:`numpy.random.RandomState.rand`

        r4   z*rand() got unexpected keyword arguments %s, r   )popfloat	TypeErrorjoinkeysrandom_sampler+   r/   kwargr4   r   r   r   randV     zRandomState.randc                 O  r   )zReturns an array of standard normal random values.

        .. seealso::
            - :func:`cupy.random.randn` for full documentation
            - :meth:`numpy.random.RandomState.randn`

        r4   z+randn() got unexpected keyword arguments %sr   r   )r   r   r   r   r   r   r   r   r   r   randnd  r   zRandomState.randn zT xzx = (x == (T)1) ? 0 : xcupy_random_x_mod_1c                 C  sz   ddl m} t|}tj||d}|jdkr|j}n|j}| j || j	|j
j|j W d    |S 1 s6w   Y  |S )Nr   r   r3   rn   )r   r   r   r9   r:   r   generateUniformgenerateUniformDoubler"   r$   r;   r<   r/   )r+   r/   r4   r   rA   r>   r   r   r   r{   u  s   

zRandomState._random_sample_rawc                 C  s&   |du rd}|  ||}t| |S )zReturns an array of random values over the interval ``[0, 1)``.

        .. seealso::
            - :func:`cupy.random.random_sample` for full documentation
            - :meth:`numpy.random.RandomState.random_sample`

        Nr   )r{   r   _mod1_kernel)r+   r/   r4   rA   r   r   r   r     s
   
zRandomState.random_samplec                 C  sz   t |}|du r|j}t |dk rtd| ||}t j||d}t j|d|d}t j||d}t j|||d}|S )a%  Returns an array of samples drawn from a rayleigh distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.rayleigh` for full documentation
            - :meth:`numpy.random.RandomState.rayleigh`
        Nr   rc   r   g       )	r9   rF   rE   rd   re   r{   r   r   r   rg   r   r   r   rayleigh  s   
zRandomState.rayleighzT max, T mxzT outz3out = max - (mx != max ? (max - mx) % (mx + 1) : 0) cupy_random_interval_upper_limitzT samplez$if (mx != max) { sample %= mx + 1; }"cupy_random_interval_sample_moduloc                 C  s  |du rd}nt |tr|f}t|}|rX|dkr"tj|tjdS |dk r-td||t	kr?tj}|t	d|d   }nY|t
krQtj}|t
d|d   }nGtd	||j}|tjkse|tjkrvtj}|j|d
d}| t	|}n"|tjks|tjkrtj}|j|d
d}| t
|}ntd|ttj|d}|dkrtj||dS | ||}|r|d }|d| d > krd| > d }	||	M }||S | ||d
}
|
j}|dkrt|s||
 }|dkr=|rt|d dn|j}| ||}| ||d}|j}||kr||d|  ||
< d}n|| ||
d| < |
|d }
|s5||d }||8 }|dks|rE||; }n|tjkrS| t	||}n| t
||}||S )a`  Generate multiple integers independently sampled uniformly from ``[0, mx]``.

        Args:
            mx (int): Upper bound of the interval
            size (None or int or tuple): Shape of the array or the scalar
                returned.
        Returns:
            int or cupy.ndarray: If ``None``, an :class:`cupy.ndarray` with
            shape ``()`` is returned.
            If ``int``, 1-D array of length size is returned.
            If ``tuple``, multi-dimensional array with shape
            ``size`` is returned.
            Currently, only 32 bit or 64 bit integers can be sampled.
        Nr   r   r3   z$mx must be non-negative (actual: {})        r5               z+mx must be within uint64 range (actual: {})Fcopyzdtype must be integer, got: {}r2   i   T)r[   r\   numpyisscalarr9   zerosuint32re   format_UINT32_MAXr.   uint64r4   int32astype_interval_upper_limitint64	functoolsreduceoperatormulr:   _curand_generate
bit_lengthr=   _get_indicesr/   max_interval_sample_modulo)r+   mxr/   is_mx_scalarr4   upper_limitn_samplesamplemx1mask
ng_indicesn_ngn_supplement
supplement
ok_indicesn_okr   r   r   	_interval  s   






zRandomState._intervalc                 C  sl   ddl m} tj|f|d}|jtjdj}| j |	| j
|jj| W d    |S 1 s/w   Y  |S )Nr   r   r3   )r   r   r9   r:   viewr   r   r/   r"   generater$   r;   r<   )r+   numr4   r   r   size32r   r   r   r     s   
zRandomState._curand_generatec                 C  sh   |j dk rtjntj}|r||kn||k}tj||d}~tjt|d f|d}| j|||j d |S )Nr   r3   rX   r/   )	r/   r   r   r   r9   cumsumr:   r\   _kernel_get_indices)r+   r   r   condr4   flagscsumindicesr   r   r   r     s   zRandomState._get_indicesz
raw U csumzraw U indiceszo
        int j = 0;
        if (i > 0) { j = csum[i-1]; }
        if (csum[i] > j) { indices[j] = i; }
        cupy_get_indicesc                 C  s"  ddl m} |du r+zttd}t|d}W nG ty*   t d t	 }Y n7w t
|tjrBttj|dd dd d}nt|}|jjd	vrQtd
t|}|dk s]|dkratd| j# || j| | j|j|jfvr||| jd || _W d   dS 1 sw   Y  dS )zResets the state of the random number generator with a seed.

        .. seealso::
            - :func:`cupy.random.seed` for full documentation
            - :meth:`numpy.random.RandomState.seed`

        r   r   N      i@B F)usedforsecuritybiuzSeed must be an integer.r   z/Seed must be an integer between 0 and 2**64 - 1)r   r   binasciihexlifyosurandomr\   NotImplementedErrortimer.   r[   r   r   hashlibmd5	hexdigestrF   r4   kindr   re   r"   setPseudoRandomGeneratorSeedr$   r)   CURAND_RNG_PSEUDO_MT19937CURAND_RNG_PSEUDO_MTGP32setGeneratorOffsetr-   )r+   r*   r   seed_strseed_arrr   r   r   r*   0  s@   

"zRandomState.seedc                 C  s"   | j ||d}ttj|d  S )zReturns an array of samples drawn from the standard cauchy distribution.

        .. seealso::
            - :func:`cupy.random.standard_cauchy` for full documentation
            - :meth:`numpy.random.RandomState.standard_cauchy`
        r   g      ?)uniformr9   tanpir+   r/   r4   ri   r   r   r   standard_cauchyU  s   zRandomState.standard_cauchyc                 C  s(   |du rd}|  ||}tj||d S )zReturns an array of samples drawn from the standard exp distribution.

         .. seealso::
            - :func:`cupy.random.standard_exponential` for full documentation
            - :meth:`numpy.random.RandomState.standard_exponential`
        Nr   r   )r{   r9   r   r%  r   r   r   rf   _  s   z RandomState.standard_exponentialc                 C  rR   )zReturns an array of samples drawn from a standard gamma distribution.

        .. seealso::
            - :func:`cupy.random.standard_gamma` for full documentation
            - :meth:`numpy.random.RandomState.standard_gamma`
        NrD   )r9   rF   rE   r:   r1   r/   r   r^   )r+   rE   r/   r4   rK   r0   r   r   r   standard_gammak  rW   zRandomState.standard_gammac                 C  s   | j ||dS )zReturns samples drawn from the standard normal distribution.

        .. seealso::
            - :func:`cupy.random.standard_normal` for full documentation
            - :meth:`numpy.random.RandomState.standard_normal`

        r   )r   )r+   r/   r4   r   r   r   r   z  s   zRandomState.standard_normalc                 C  rR   )zReturns an array of samples drawn from the standard t distribution.

        .. seealso::
            - :func:`cupy.random.standard_t` for full documentation
            - :meth:`numpy.random.RandomState.standard_t`
        NrD   )r9   rF   rE   r:   r1   r/   r   standard_t_kernelrT   r   r   r   
standard_t  rW   zRandomState.standard_tc                 C  s   ddl m} |du rd}tj|tjd}|jjd }| j || j	|j
j|j|  W d   n1 s5w   Y  |ttjjM }|S )a  Draws integers between 0 and max integer inclusive.

        Return a sample of uniformly distributed random integers in the
        interval [0, ``np.iinfo(np.int_).max``]. The `np.int_` type translates
        to the C long integer type and its precision is platform dependent.

        Args:
            size (int or tuple of ints): Output shape.

        Returns:
            cupy.ndarray: Drawn samples.

        .. seealso::
            :meth:`numpy.random.RandomState.tomaxint`

        r   r   Nr   r3      )r   r   r9   r:   int_r4   itemsizer"   r  r$   r;   r<   r/   iinfor   )r+   r/   r   r   size_in_intr   r   r   tomaxint  s   zRandomState.tomaxintzL left, M mode, R righta  
        T base, leftbase, ratio, leftprod, rightprod;

        base = right - left;
        leftbase = mode - left;
        ratio = leftbase / base;
        leftprod = leftbase*base;
        rightprod = (right - mode)*base;

        if (x <= ratio)
        {
            x = left + sqrt(x*leftprod);
        } else
        {
            x = right - sqrt((1.0 - x) * rightprod);
        }
        cupy_triangular_kernelc                 C  s   t |t |t |}}}t ||krtdt ||kr'tdt ||kr2td|du r>t |||j}| j||d}t||||S )a-  Returns an array of samples drawn from the triangular distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.triangular` for full documentation
            - :meth:`numpy.random.RandomState.triangular`
        zleft > modezmode > rightzleft == rightNr   )	r9   rF   rd   re   rG   rE   r   r   _triangular_kernel)r+   leftmoderightr/   r4   ri   r   r   r   
triangular  s   zRandomState.triangularzT low, T highzx = T(low) + x * T(high - low)
cupy_scalec                 C  sh   t |st||}t |st||}|du r!t||j}t |}| j||d}t	|||S )zReturns an array of uniformly-distributed samples over an interval.

        .. seealso::
            - :func:`cupy.random.uniform` for full documentation
            - :meth:`numpy.random.RandomState.uniform`

        Nr   )
r   r   r9   rF   rG   rE   r4   r   r   _scale_kernel)r+   lowhighr/   r4   r   r   r   r   r"    s   


zRandomState.uniformc                 C  rC   )zReturns an array of samples drawn from the von Mises distribution.

        .. seealso::
            - :func:`cupy.random.vonmises` for full documentation
            - :meth:`numpy.random.RandomState.vonmises`
        NrD   )	r9   rF   rG   rE   r:   r1   r/   r   vonmises_kernel)r+   mukappar/   r4   rK   r0   r   r   r   vonmises  rM   zRandomState.vonmiseszT mean, T scale, T UzT Xa	  
            T mu_2l;
            T Y;
            mu_2l = mean / (2*scale);
            Y = mean*X*X;
            X = mean + mu_2l*(Y - sqrt(4*scale*Y + Y*Y));
            if (U > mean/(mean+X))
            {
                X = mean*mean/X;
            }
        cupy_wald_scalec                 C  s`   t j||dt j||d}}|du rt ||j}| j||d}| j||d}t||||S )zReturns an array of samples drawn from the Wald distribution.

         .. seealso::
            - :func:`cupy.random.wald` for full documentation
            - :meth:`numpy.random.RandomState.wald`
        r3   Nr   )r9   rF   rG   rE   r   r   r   _wald_kernel)r+   r   rh   r/   r4   ri   r   r   r   r   wald  s   zRandomState.waldc                 C  sR   t |}t |dk rtd|du r|j}| ||}t j|d| |d |S )a$  Returns an array of samples drawn from the weibull distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.weibull` for full documentation
            - :meth:`numpy.random.RandomState.weibull`
        r   r   Nrb   r   )r9   rF   rd   re   rE   rf   r   r   r   r   r   weibull'  s   
zRandomState.weibullc                 C  sZ   t |}t |dkrtd|du r|j}t j||d}| |j}t	||| |S )a  Returns an array of samples drawn from the Zipf distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.zipf` for full documentation
            - :meth:`numpy.random.RandomState.zipf`
        rb   z'a' must be a valid float > 1.0NrD   )
r9   rF   rd   re   rE   r:   r1   r/   r   zipf_kernel)r+   rI   r/   r4   rK   r0   r   r   r   zipf=  s   
zRandomState.zipfTc                 C  sp  |du rt dt|tjr|jdkrtt|tr%|}|dk r$t dntj|dd}|jdkr5t dt|}|durpt|}|jdkrKt dt||krUt d	|dk	 s_t d
t
| }t|dspt d|du rxtd|}ztj|}W n	 ty   Y nw |dkr|dkrt d|s|du r||k rt dt|trtj}| |}	tj|	}
|
jdtd |tjd}t||}||}||S | }| | |d| |S |st|dur| }||d  }| |}|j|dd}n|dkrd}| j d||d}|j!tj"dd}t|tr$|S |jdkr4tj|| |j#dS || S )zReturns an array of random values from a given 1-D array.

        .. seealso::
            - :func:`cupy.random.choice` for full documentation
            - :meth:`numpy.random.choice`

        Nz%a must be 1-dimensional or an integerr   z$a must be greater than or equal to 0Fr   r5   zp must be 1-dimensionalza and p must have same sizez"probabilities are not non-negativezprobabilities do not sum to 1z5choice() without specifying size is not supported yetz-a cannot be empty unless no samples are takenz@Cannot take a larger sample than population when 'replace=False'r   rX   r4  )sider  r3   )$re   r[   r9   r   ndimr  r\   arrayr   allr_   getr   r   r   r7   r8   r   r   
num_roundsr1   randomdefault_rngintegersr   r   r=   r   shuffler  r   searchsortedrandintr   r   r4   )r+   rI   r/   replacerP   a_sizep_sumrE   n_roundsr0   rngr   	bijectionr  cdfuniform_samplesindexr   r   r   choiceR  s   











zRandomState.choicec                 C  sD   t |tjs
td|jdkrtd|| t| |dd< dS )zReturns a shuffled array.

        .. seealso::
            - :func:`cupy.random.shuffle` for full documentation
            - :meth:`numpy.random.shuffle`

        zThe array must be cupy.ndarrayr   z)An array whose ndim is 0 is not supportedN)r[   r9   r   r   rE  _permutationr   r+   rI   r   r   r   rM    s
   
zRandomState.shufflec                 C  s&   t |tr
| |S || t| S )z6Returns a permuted range or a permutation of an array.)r[   r\   rZ  r   r[  r   r   r   permutation  s   

zRandomState.permutationc                 C  sf   ddl m} tj|ftjd}| j || j|j	j
| W d   n1 s'w   Y  t|}|S )zReturns a permuted range.r   r   r3   N)r   r   r9   r:   r   r   r"   r  r$   r;   r<   argsort)r+   r  r   r   rF  r   r   r   rZ    s   
zRandomState._permutationz$y = T(loc) - log(-log(x)) * T(scale)cupy_gumbel_kernelc                 C  sd   t |st||}t |st||}|du r!t||j}| j||d}t|||| |S )zReturns an array of samples drawn from a Gumbel distribution.

        .. seealso::
            - :func:`cupy.random.gumbel` for full documentation
            - :meth:`numpy.random.RandomState.gumbel`
        Nr   )	r   r   r9   rF   rG   rE   r{   r   _gumbel_kernelr}   r   r   r   gumbel  s   

zRandomState.gumbelc                 C  st  t |s\t|}|du rt|}|d }n	|}t|d }|du r,t||j}|| }tt	j
|d}| | |}	|	|}	t|	|}	|j|dd}tj|	||	d |	S |du rid}t|d }
n
t|}t|d }
||
kr{td|t|jk rtdt|j|
t|jkrtd	t|j|
| }| ||j|dd}tj|||d |S )
zReturns a scalar or an array of integer values over ``[low, high)``.

        .. seealso::
            - :func:`cupy.random.randint` for full documentation
            - :meth:`numpy.random.RandomState.randint`
        Nr5   Fr   r   r   zlow >= highzlow is out of bounds for {}zhigh is out of bounds for {})r   r   r9   rF   
zeros_likerG   rE   r   r   r   r   r  flattenr   r=   r   r\   re   r-  minr   r4   r   r   )r+   r8  r9  r/   r4   lohidifftotal_elemsrA   hi1ri   r   r   r   rO    sP   






zRandomState.randint)NN)Nrp   )rb   Nrp   r
   )NTN)D__name__
__module____qualname____doc__r,   r1   rB   r   rL   r\   rQ   rV   ra   rj   rn   ro   rs   rx   r   ElementwiseKernelr|   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&  rf   r'  r   r)  r/  r1  r5  r7  r"  r=  r?  r@  rA  rC  rY  rM  r\  rZ  r_  r`  rO  r   r   r   r   r   .   s    




`
c
	
	%


 
\
r   c                 C  s   t  |  dS )a  Resets the state of the random number generator with a seed.

    This function resets the state of the global random number generator for
    the current device. Be careful that generators for other devices are not
    affected.

    Args:
        seed (None or int): Seed for the random number generator. If ``None``,
            it uses :func:`os.urandom` if available or :func:`time.time`
            otherwise. Note that this function does not support seeding by
            an integer array.

    N)get_random_stater*   )r*   r   r   r   r*     s   r*   c                   C  s   i a d S r
   )_random_statesr   r   r   r   reset_states/  s   rp  c                  C  sX   t  } t| jd}|du r*td}|durtt	|}t
|}t| j|}|S )aX  Gets the state of the random number generator for the current device.

    If the state for the current device is not created yet, this function
    creates a new one, initializes it, and stores it as the state for the
    current device.

    Returns:
        RandomState: The state of the random number generator for the
        device.

    N	CUPY_SEED)r   Devicero  rH  idr  getenvr   r   r\   r   
setdefault)devrsr*   r   r   r   rn  5  s   
rn  c                 C  s,   t | tstdt| | tt < dS )zSets the state of the random number generator for the current device.

    Args:
        state(RandomState): Random state to set for the current device.
    z;Random state must be an instance of RandomState. Actual: {}N)r[   r   r   r   typero  r   get_device_id)rw  r   r   r   set_random_stateL  s   

rz  c                 C  s    t | } | jdvrtd| S )N)rn   dz-cupy.random only supports float32 and float64)r   r4   r   r   r3   r   r   r   r   Y  s   

r   r
   )'
__future__r   atexitr  r   r  r   r  r  r    r%   r   r   numpy.linalgr   r9   r   r   	cupy.cudar   cupy.randomr   cupy.random._generator_apir   r	   r   r   r   r   r   r.   r   r*   ro  registerrp  rn  rz  r   r   r   r   r   <module>   sV    
         
t
