a
    Ad                     @   st   d Z ddlZddgZddgZejdgejdZejd	gejdZd
d Z	dd Z
dddZdd ZG dd dZdS )a1  RNG imitiating torch cuda randn on CPU. You are welcome.

Usage:

```
g = Generator(seed=0)
print(g.randn(shape=(3, 4)))
```

Expected output:
```
[[-0.92466259 -0.42534415 -2.6438457   0.14518388]
 [-0.12086647 -0.57972564 -0.62285122 -0.32838709]
 [-1.07454231 -0.36314407 -1.67105067  2.26550497]]
```
    Nl   S$ l   W= l   yn< l   .v g"=dtypegϖZ!>c                 C   s   |  tjddddS )z:Converts (N,) np.uint64 array into (2, N) np.unit32 array.      r   )viewnpuint32reshape	transpose)x r   :/var/www/html/stable-diffusion-webui/modules/rng_philox.pyr	      s    r	   c                 C   s   t | d tjtd  }t | d tjtd  }|d | d A |d A | d< |d | d< |d | d A |d A | d< |d | d< dS )z:A single round of the Philox 4x32 random number generator.r   r   r      N)r	   astyper   uint64philox_m)counterkeyv1v2r   r   r   philox4_round    s    r   
   c                 C   sR   t |d D ]6}t| | |d td  |d< |d td  |d< qt| | | S )a  Generates 32-bit random numbers using the Philox 4x32 random number generator.

    Parameters:
        counter (numpy.ndarray): A 4xN array of 32-bit integers representing the counter values (offset into generation).
        key (numpy.ndarray): A 2xN array of 32-bit integers representing the key values (seed).
        rounds (int): The number of rounds to perform.

    Returns:
        numpy.ndarray: A 4xN array of 32-bit integers containing the generated random numbers.
    r   r   )ranger   philox_w)r   r   rounds_r   r   r   
philox4_32,   s    

r   c                 C   sN   | t  t d  }|t td  }tdt| }|t| }|tjS )uX   Returns just the first out of two numbers generated by Box–Muller transform algorithm.r   g       )two_pow32_invtwo_pow32_inv_2pir   sqrtlogsinr   float32)r   yuvsr1r   r   r   
box_mullerB   s
    r)   c                   @   s    e Zd ZdZdd Zdd ZdS )	GeneratorzHRNG that produces same outputs as torch.randn(..., device='cuda') on CPUc                 C   s   || _ d| _d S )Nr   )seedoffset)selfr+   r   r   r   __init__P   s    zGenerator.__init__c                 C   s   d}|D ]}||9 }qt jd|ft jd}| j|d< t j|t jd|d< |  jd7  _t j|t jd}|| j t|}t	||}t
|d |d |S )zGenerate a sequence of n standard normal random variables using the Philox 4x32 random number generator and the Box-Muller transform.r      r   r   r   )r   zerosr	   r,   arangeemptyr   fillr+   r   r)   r
   )r-   shapenr   r   r   gr   r   r   randnT   s    


zGenerator.randnN)__name__
__module____qualname____doc__r.   r7   r   r   r   r   r*   M   s   r*   )r   )r;   numpyr   r   r   arrayr#   r   r   r	   r   r   r)   r*   r   r   r   r   <module>   s   
