
    2Vh                         d dl 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  ed       G d d	             Zd
 Zd Zd Zy)    N)backend)keras_export)global_state)	jax_utils)	auto_namezkeras.random.SeedGeneratorc                   6    e Zd ZdZddZddZd Zed        Zy)	SeedGeneratoraR  Generates variable seeds upon each call to a function generating
    random numbers.

    In Keras, all random number generators (such as
    `keras.random.normal()`) are stateless, meaning that if you pass an
    integer seed to them (such as `seed=42`), they will return the same
    values for repeated calls. To get different values for each
    call, a `SeedGenerator` providing the state of the random generator
    has to be used.

    Note that all the random number generators have a default seed of None,
    which implies that an internal global SeedGenerator is used.
    If you need to decouple the RNG from the global state you can provide
    a local `StateGenerator` with either a deterministic or random initial
    state.

    Remark concerning the JAX backen: Note that the use of a local
    `StateGenerator` as seed argument is required for JIT compilation of
    RNG with the JAX backend, because the use of global state is not
    supported.

    Example:

    ```python
    seed_gen = keras.random.SeedGenerator(seed=42)
    values = keras.random.normal(shape=(2, 3), seed=seed_gen)
    new_values = keras.random.normal(shape=(2, 3), seed=seed_gen)
    ```

    Usage in a layer:

    ```python
    class Dropout(keras.Layer):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.seed_generator = keras.random.SeedGenerator(1337)

        def call(self, x, training=False):
            if training:
                return keras.random.dropout(
                    x, rate=0.5, seed=self.seed_generator
                )
            return x
    ```
    Nc           	      (    |t         j                  j                        }| _        |j	                  dd       }|rt        d|       || _        nt         _         _        
t               t        t              st        d        fd} j                  j                   j                         5   j                  j                  |d j                  j                         ddd	
       _        d d d        y # 1 sw Y   y xY w)Nr   z Unrecognized keyword arguments: z3Argument `seed` must be an integer. Received: seed=c                  f    |j                  dd       }j                  j                  dg|      S )Ndtyper   r   )getr   convert_to_tensor)argskwargsr   seedselfs      O/home/dcms/DCMS/lib/python3.12/site-packages/keras/src/random/seed_generator.pyseed_initializerz0SeedGenerator.__init__.<locals>.seed_initializerR   s1    JJw-E<<114)51II    )caller)   Fnoneseed_generator_state)shaper   	trainableaggregationname)r   	__class____name__r   pop
ValueErrorr   _initial_seedmake_default_seed
isinstanceint
name_scopeVariablerandom_seed_dtypestate)r   r   r   r   custom_backendr   s   ``    r   __init__zSeedGenerator.__init__<   s   <T^^445D	It4?xHII%)DL"DL!<$&D$$EdVL 	J \\$$TYYt$< 	.. ll446"+ / DJ	 	 	s    ?DDc                    | j                   }|j                  dz  }|r}| j                  j                  t	        j
                  ddg      |j                        }| j                   j                  | j                  j                  j                  ||             |S | j                   j                  |dz   dz  dz         |S )N   r   r   i  iO= )
r*   valuer   r   nparrayr   assignnumpyadd)r   ordered
seed_statenew_seed_value	increments        r   nextzSeedGenerator.next`   s    ZZ
#))A-66!Q 
(8(8 7 I JJdll0044ZKL
  JJzA~5>?r   c                     d| j                   iS )Nr   )r#   )r   s    r   
get_configzSeedGenerator.get_configo   s    **++r   c                      | di |S )N r=   )clsconfigs     r   from_configzSeedGenerator.from_configr   s    }V}r   )NN)T)	r    
__module____qualname____doc__r,   r9   r;   classmethodr@   r=   r   r   r	   r	      s,    ,\"H,  r   r	   c                      t        j                         rt        d      t        j                  d      } |  t               } t        j                  d|        | S )Na  [JAX RNG] When tracing a JAX function, you should only use seeded random ops, e.g. you should create a `SeedGenerator` instance, attach it to your layer/model, and pass the instance as the `seed` argument when calling random ops. Unseeded random ops would get incorrectly traced by JAX and would become constant after tracing. Example:

```
# Make sure to set the seed generator as a layer attribute
self.seed_generator = keras.random.SeedGenerator(seed=1337)
...
out = keras.random.normal(shape=(1,), seed=self.seed_generator)
```global_seed_generator)r   is_in_jax_tracing_scoper"   r   get_global_attributer	   set_global_attribute)gens    r   rF   rF   w   sU    ((*
 	
 
+
+,C
DC
{o))*A3GJr   c                  @    t        j                  dt        d            S )Nr.   g    eA)python_randomrandintr&   r=   r   r   r$   r$      s      CH--r   c                 
   ddl m} ddl m} t        | t              r| j                         S t        | t              r || dg |             S | t               j                  d      S t        d|  dt        |        d	      )
Nr   )r   )r)   r   F)r5   z\Argument `seed` must be either an integer or an instance of `SeedGenerator`. Received: seed=z
 (of type ))
keras.src.backendr   r)   r%   r	   r9   r&   rF   r"   type)r   r   r)   s      r   	draw_seedrR      s    33$&yy{	D#	 $2C2EFF	$&++E+::
	z$t*Q	8 r   )randomrL   r3   r0   	keras.srcr   keras.src.api_exportr   keras.src.backend.commonr   keras.src.utilsr   keras.src.utils.namingr   r	   rF   r$   rR   r=   r   r   <module>rY      sL       - 1 % , *+g g ,gT0.r   