
    AVh                         d 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m
Z
 dd
lmZ ddlmZ  edd       G d dej                               Zd Zd Zd Zd Zd Zd Zy)z0Utilities for random ops to share common usages.    N)constant_op)dtypes)tensor)	array_ops)array_ops_stack)bitwise_ops)gen_stateless_random_ops_v2)math_ops)	tf_exportzrandom.Algorithmzrandom.experimental.Algorithmc                       e Zd ZdZdZdZdZy)	Algorithma  A random-number-generation (RNG) algorithm.

  Many random-number generators (e.g. the `alg` argument of
  `tf.random.Generator` and `tf.random.stateless_uniform`) in TF allow
  you to choose the algorithm used to generate the (pseudo-)random
  numbers. You can set the algorithm to be one of the options below.

  * `PHILOX`: The Philox algorithm introduced in the paper ["Parallel
    Random Numbers: As Easy as 1, 2,
    3"](https://www.thesalmons.org/john/random123/papers/random123sc11.pdf).
  * `THREEFRY`: The ThreeFry algorithm introduced in the paper
    ["Parallel Random Numbers: As Easy as 1, 2,
    3"](https://www.thesalmons.org/john/random123/papers/random123sc11.pdf).
  * `AUTO_SELECT`: Allow TF to automatically select the algorithm
    depending on the accelerator device. Note that with this option,
    running the same TF program on different devices may result in
    different random numbers. Also note that TF may select an
    algorithm that is different from `PHILOX` and `THREEFRY`.
           N)__name__
__module____qualname____doc__PHILOXTHREEFRYAUTO_SELECT     U/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/random_ops_util.pyr   r      s    * &(+r   r   c                 J   t        | t              r| S t        | t              r| j                  S t        | t        j
                        r| S t        | t              r| j                         j                         j                  dd      j                  dd      }|dk(  rt        j                  j                  S |dk(  rt        j                  j                  S |dk(  rt        j                  j                  S t        t        |             t        d|  dt!        |        d	      )
a  Converts algorithm to an integer.

  Args:
    alg: can be one of these types: integer, Algorithm, Tensor, string. Allowed
      strings are "philox" and "threefry".

  Returns:
    An integer, unless the input is a Tensor in which case a Tensor is returned.
  - _philoxthreefry
autoselectz'Can't convert argument `alg` (of value z
 and type z	) to int.)
isinstanceintr   valuer   Tensorstrstriplowerreplacer   r   r   
ValueErrorunsupported_alg_error_msg	TypeErrortype)alg	canon_algs     r   convert_alg_to_intr0   :   s     SJY99V]]#JS		!!#++C4<<S"EIH###	j	 %%%	l	"""(((0566

1#jc L 	 r   c                 
   |t         j                  j                  k(  rt        j                  |       \  }}||fS |t         j
                  j                  k(  rt        |       \  }}||fS |t         j                  j                  k(  rkt        j                  t        t        j                  | t        j                              dg      }t        j                  dgt        j                         }||fS t#        t%        |            )a  Calculates the key and counter to pass to raw RNG ops.

  This function calculates the key and counter that will be passed to
  the raw RNG ops like `StatelessRandomUniformV2`. Depending on the
  input `alg`, the key and counter may be scrambled or copied from
  `seed`. If `alg` is `"auto_select"`, the key and counter will be
  determined at runtime based on device type.

  Args:
    seed: An integer tensor of shape [2]. The seed to calculate the key and
      counter from.
    alg: The RNG algorithm. See `tf.random.stateless_uniform` for an
      explanation.

  Returns:
    A pair (key, counter) suitable for V2 stateless RNG ops like
    `StatelessRandomUniformV2`.
  r   )r   r   r$   r	    stateless_random_get_key_counterr   _philox_scramble_seedr   r   reshape_uint32s_to_uint64r
   castr   uint32zerosuint64r*   r+   seedr.   keycounters       r   _get_key_counterr>   \   s    & 	I!!'''.OOLC 
g i$$$(.LC 
g i  &&&


8==v}}=>C ooqc6==1G 
g .s3
44r   c                 x    |t         j                  j                  }t        |      }t	        | |      \  }}|||fS )a  Calculates the key, counter and algorithm to pass to raw RNG ops.

  This function calculates the key and counter, and determines the algorithm
  that will be passed to the raw RNG ops like `StatelessRandomUniformV2`.
  Depending on the input `alg`, the key and counter may be scrambled or copied
  from `seed`. If `alg` is `"auto_select"`, the key and counter will be
  determined at runtime based on device type.

  Args:
    seed: An integer tensor of shape [2]. The seed to calculate the key and
      counter from.
    alg: The RNG algorithm. See `tf.random.stateless_uniform` for an
      explanation.

  Returns:
    A pair (key, counter, algorithm) suitable for V2 stateless RNG ops like
    `StatelessRandomUniformV2`.
  )r   r   r$   r0   r>   r:   s       r   get_key_counter_algr@      sA    & 	[



%
%C3#!$,,#w	gs	r   c           
      .   t        j                  t        j                  | d   t        j
                        t        j                  t        j                  | d   t        j
                        t        j                  dt        j
                                    S )Nr   r       )	r   
bitwise_orr
   r6   r   r9   
left_shiftr   constant)xs    r   r5   r5      sc    			mmAaD&--(
--!fmm
,


r6==
1
 r   c           	      l   t        | t              rOt        j                  j                  }t        j
                  j                  }t        j                  j                  }nGt        | t              rd}d}d}n0t        j                  }t        j
                  }t        j                  }d|  d| d| d| d	S )	z1Produces the unsupported-algorithm error message.r   r    auto_selectz%Argument `alg` got unsupported value z. Supported values are z for the Philox algorithm, z! for the ThreeFry algorithm, and z for auto-selection.)r"   r#   r   r   r$   r   r   r&   )r.   r   r    rH   s       r   r+   r+      s    S##F!!''H''--K#sFHKF!!H''K-cU2I	+	
3	)+r   c                    t        j                  dgt        j                        }t	        j
                  | t        j                        }t        j                  dg||t        j                  t        j                  j                        }t        j                  t        |dd       dg      }t        j                   dt        |dd       gd      }||fS )	a  Determines the key and counter for Philox PRNG with the given seed.

  Args:
    seed: An integer tensor of shape [2]. The seed to calculate the key and
      counter from.

  Returns:
    A pair (key, counter) suitable for V2 stateless RNG ops like
    `StatelessRandomUniformV2`.
  l    w}x0   )r<   r=   dtyper.   Nr   r   r   )axis)r   rE   r   r9   r
   r6   r	   $stateless_random_uniform_full_int_v2r7   r   r   r$   r   r4   r5   r   stack)r;   r<   r=   mixs       r   r3   r3      s     	016==A#MM$.'#HHc
MM



 
 	# 	,S!W5s;#!!1&8QR&A"BK'	gr   )r   enumtensorflow.python.frameworkr   r   r   tensorflow.python.opsr   r   r   r	   r
    tensorflow.python.util.tf_exportr   Enumr   r0   r>   r@   r5   r+   r3   r   r   r   <module>rU      sq    7  3 . . + 1 - = * 6 >?		  @6D F4,r   