o
    灛iP                     @   s  d dl mZ ddlmZ ddlmZ dZeefdejfddZeefdejfd	d
Z	eefdejfddZ
eefdejfddZedd ZeefdejfddZeefdejfddZedd ZeefdejfddZeefdejfddZdS )   )jit   )core)math
   n_roundsc                 C   s   | j tjkrd}d}d}	d}
nt| j tjkd d}d}d}	d	}
t|D ]/}|	}|
}| |}}t|||A |A } t|||A |A }|| }|| }|| }|| }q&| |||fS )
zV
    Run `n_rounds` rounds of Philox for state (c0, c1, c2, c3) and key (k0, k1).
    l   yn< l   .v l   S$ l   W= z"dtype not supported in philox_impll   |~fq	 l   ;'	:=[ l   lB;: l   W$*	R )dtypetluint32static_assertuint64static_ranger   umulhi)c0c1c2c3k0k1r   PHILOX_KEY_APHILOX_KEY_BPHILOX_ROUND_APHILOX_ROUND_B_AB_c0_c2 r   X/sda-disk/www/egybert/egybert_env/lib/python3.10/site-packages/triton/language/random.pyphilox_impl   s*   

r    c           	      C   s   t | } t |}t |}t |}t |}| t j} t |jjdkr>t j}| d? d@ t j}| d@ t j}nt t |jjdkd t j}t j	dd|d}| }|j|dd	}|j|dd	}|j|dd	}|j|dd	}t
|||||||S )
N    l    @   z bitwidth not supported in philox)r       )r   Tbitcast)r	   	to_tensortor   	constexprr   primitive_bitwidthr
   r   fullr    )	seedr   r   r   r   r   	int_dtypeseed_hiseed_lor   r   r   philox-   s&   




r/   c                 C   s   t | ||\}}}}|S )aq  
    Given a :code:`seed` scalar and an :code:`offset` block, returns a single
    block of random :code:`int32`.

    If you need multiple streams of random numbers,
    using `randint4x` is likely to be faster than calling `randint` 4 times.

    :param seed: The seed for generating random numbers.
    :param offset: The offsets to generate random numbers for.
    )	randint4x)r+   offsetr   retr   r   r   r   randintE   s   r3   c                 C   s   |d }t | |||||S )aU  
    Given a :code:`seed` scalar and an :code:`offset` block, returns four
    blocks of random :code:`int32`.

    This is the maximally efficient entry point
    to Triton's Philox pseudo-random number generator.

    :param seed: The seed for generating random numbers.
    :param offsets: The offsets to generate random numbers for.
    r#   )r/   )r+   r1   r   _0r   r   r   r0   U   s   r0   c                 C   s   t | jt jkst | jt jkr| jt jdd} d}nt t | jt jkp0t | jt jk | jt jdd} d}t 	| dk |  d | } | | S )zo
    Numerically stable function to convert a random uint into a random float uniformly sampled in [0, 1).
    Tr$   g=g   ;r#   r   )
r	   r(   r   r
   int32r'   r   r   int64where)xscaler   r   r   uint_to_uniform_floats   s   $*r:   c                 C   s   t | ||}t|S )z
    Given a :code:`seed` scalar and an :code:`offset` block,
    returns a block of random :code:`float32` in :math:`U(0, 1)`.

    :param seed: The seed for generating random numbers.
    :param offsets: The offsets to generate random numbers for.
    )r3   r:   )r+   r1   r   sourcer   r   r   rand   s   	r<   c                 C   s@   t | ||\}}}}t|}t|}t|}	t|}
|||	|
fS )a   
    Given a :code:`seed` scalar and an :code:`offsets` block,
    returns 4 blocks of random :code:`float32` in :math:`U(0, 1)`.

    :param seed: The seed for generating random numbers.
    :param offsets: The offsets to generate random numbers for.
    )r0   r:   )r+   offsetsr   i1i2i3i4u1u2u3u4r   r   r   rand4x   s   	rF   c                 C   sD   t d| } d| }tdt|  }|t| |t| fS )zBox-Muller transformgHz>g-DT!@g       )r	   maximumr   sqrtlogcossin)rB   rC   thrr   r   r   pair_uniform_to_normal   s   rN   c           	      C   s6   t | ||\}}}}t|}t|}t||\}}|S )a  
    Given a :code:`seed` scalar and an :code:`offset` block,
    returns a block of random :code:`float32` in :math:`\mathcal{N}(0, 1)`.

    :param seed: The seed for generating random numbers.
    :param offsets: The offsets to generate random numbers for.
    )r0   r:   rN   )	r+   r1   r   r>   r?   r   rB   rC   n1r   r   r   randn   s
   	rP   c                 C   s<   t | ||\}}}}t||\}}t||\}	}
|||	|
fS )a	  
    Given a :code:`seed` scalar and an :code:`offset` block,
    returns 4 blocks of random :code:`float32` in :math:`\mathcal{N}(0, 1)`.

    :param seed: The seed for generating random numbers.
    :param offsets: The offsets to generate random numbers for.
    )rF   rN   )r+   r1   r   rB   rC   rD   rE   rO   n2n3n4r   r   r   randn4x   s   	rT   N)runtime.jitr    r   r	   r   N_ROUNDS_DEFAULTr(   r    r/   r3   r0   r:   r<   rF   rN   rP   rT   r   r   r   r   <module>   s0     

