a
    kh                     @   s  d dl mZ ddlmZ ddlmZ dZeefejdddZeefejdd	d
Z	eefejdddZ
eefejdddZedd ZeefejdddZeefejdddZedd ZeefejdddZeefejd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 }tj||d
d}tj||d
d}tj	||d
d}tj	||d
d}qL| |||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 F)Zsanitize_overflow)
dtypetluint32static_assertuint64Zstatic_ranger   Zumulhimuladd)c0c1c2c3Zk0Zk1r   ZPHILOX_KEY_AZPHILOX_KEY_BZPHILOX_ROUND_AZPHILOX_ROUND_B_ABZ_c0Z_c2 r   D/var/www/auris/lib/python3.9/site-packages/triton/language/random.pyphilox_impl   s*    
r   c           	      C   s  t | } t | j  | t j} t |}t |}t |}t |}t |jjdkrt j	}| d? d@ t j	}| d@ t j	}n4t 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Zbitcast)r	   Z	to_tensorr   r   Zis_inttor   	constexprprimitive_bitwidthr
   fullr   )	seedr   r   r   r   r   Z	int_dtypeZseed_hiZ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   randintH   s    r&   c                 C   sN   | tj}|d }t|jjdkr8|d?  tj}n|}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   r	   r
   r   r   r   r"   )r!   r$   r   Z	offset_loZ_0Z	offset_hir   r   r   r#   X   s    r#   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p`t | 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)xZscaler   r   r   uint_to_uniform_float~   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.
    )r&   r+   )r!   r$   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.
    )r#   r+   )r!   offsetsr   i1i2Zi3i4u1u2u3u4r   r   r   rand4x   s    	r6   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)r2   r3   thrr   r   r   pair_uniform_to_normal   s    r>   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.
    )r#   r+   r>   )	r!   r$   r   r/   r0   r   r2   r3   n1r   r   r   randn   s
    	r@   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.
    )r6   r>   )r!   r$   r   r2   r3   r4   r5   r?   Zn2Zn3Zn4r   r   r   randn4x   s    	rA   N)Zruntime.jitr    r   r	   r   ZN_ROUNDS_DEFAULTr   r   r"   r&   r#   r+   r-   r6   r>   r@   rA   r   r   r   r   <module>   s.    %

