
    6bis                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	J
s  Jr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJr  SSKJ r!  SSK"J#r#  SSK"J$r$  SSK%J&r'  SSK(J)r)  S r*S r+ SAS jr,\)" S/ S9\'RZ                              SBS j5       5       r.\R^                  " 5       r0S\0l1        S\0l2        S\0l3        S\0l4        \#Rj                  S 5       r6\#Rj                  S 5       r7S r8\#Rj                  S 5       r9S r:S r;S r<SAS jr=S  r> " S! S"\R~                  5      r@ " S# S$\R~                  5      rAS% rBS& rCS' rD " S( S)\R~                  5      rE " S* S+\R~                  5      rF      SCS, jrG " S- S.\R                  5      rI " S/ S0\R~                  5      rJ " S1 S2\R~                  5      rK SDS3 jrL\R                  \R                  \R                  \R                  \R                  \!R                  \R                  S4.rTS5 rUSES6 jrVS7 rWS8 rXS9 rY\Rj                  S: 5       rZ\Rj                  S; 5       r[S< r\S= r]S> r^SAS? jr_S@ r`g)Fz$Utilities for unit-testing TF-Keras.    N)backend)layers)models)base_layer_utils)adadelta)adagrad)adam)adamax)gradient_descent)nadam)rmsprop)tf_contextlib)
tf_inspect)	test_util)keras_exportc                 B    [         R                  R                  X5        g N)nptestingassert_array_equalactualexpecteds     _/home/james-whalen/.local/lib/python3.13/site-packages/tf_keras/src/testing_infra/test_utils.pystring_testr   1   s    JJ!!&3    c                 B    [         R                  R                  XSSS9  g )NgMbP?gư>)rtolatol)r   r   assert_allcloser   s     r   numeric_testr!   5   s    JJvdFr   c                    Ub  [         R                  R                  U5        X-   nSU-  [         R                  R                  U4U-   5      -  n[         R                  R                  SX54S9n[         R                  " U4U-   [         R
                  S9n[        U5       H,  n	XgU	      [         R                  R                  SSUS9-   X'   M.     USU  USU  4XS XpS 44$ )a  Generates test data to train a model on.

Args:
  train_samples: Integer, how many training samples to generate.
  test_samples: Integer, how many test samples to generate.
  input_shape: Tuple of integers, shape of the inputs.
  num_classes: Integer, number of classes for the data and targets.
  random_seed: Integer, random seed used by numpy to generate data.

Returns:
  A tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.
N   r   )size)dtypeg      ?)locscaler$   )r   randomseedrandintzerosfloat32rangenormal)
train_samplestest_samplesinput_shapenum_classesrandom_seed
num_sample	templatesyxis
             r   get_test_datar9   9   s     
		{#-JK"))"2"2K>K3O"PPI
		![}=A
*,BJJ?A:1!1!1; "2 "
 
 
 
>M	An}-.	
>	An-. r   z#keras.__internal__.utils.layer_test)v1c                 `  ^ ^^! Uc  Uc  [        S5      eU(       d  Sn[        U5      n[        U5       H,  u  pUb  M
  [        R                  R                  SS5      X'   M.     S[        R                  R	                  U5      -  nUSS S:X  a  US	-  nUR                  U5      nOUc  UR                  nUc  UR                  nUc  Un[        R                  " U5      [        R                  :X  a  U(       a  UR                  nO![        nOU(       a  UR                  nO[        nT=(       d    0 mT " S0 TD6nUb?  UR                   U:w  a/  [#        S
T R$                  < SUR                   < SU< ST< 35      eU	b  UR'                  U	5        UR)                  5       nUR+                  U5        S[,        R.                  " T R0                  5      ;   a  UTS'   T " S0 TD6n[2        R4                  " USS US9m!U" T!5      n[6        R                  " U5      U:w  a=  [#        S
T R$                  < ST!< S[6        R                  " U5      < SU< ST< 3
5      eUU U!4S jnUb'  U" [        R8                  " U5      UR                  5        [:        R<                  " T!U5      n[?        URA                  [        R8                  " U5      5      RC                  5       5      nURE                  [        RF                  " X#S95      nURI                  U5      nUR                  nU" UU5        U" UR                  U5        UR                  UR                  :w  a=  [#        S
T R$                  < ST!< SUR                  < SUR                  < ST< 3
5      eUb	  U" UU5        URK                  5       n[:        R<                  RM                  UU
5      nURN                  (       a;  UR)                  5       nUR+                  U5        URI                  U5      nU" UU5        UR)                  5       nU(       an  [:        R<                  " T!U" T!5      5      n[P        RR                  b  URU                  SSS/[W        5       S9  OURU                  SSS/S9  URY                  UU5        URK                  5       nUUS'   URZ                  RM                  U5      nU	b  UR'                  U	5        [:        R\                  " 5       nUR_                  [2        R4                  " USS US95        UR_                  U5        UR+                  U5        URI                  U5      nUR                  n[a        UU5       H:  u  nn Uc  M  UU :w  d  M  [#        S
T R$                  < ST!< SU< SU< ST< 3
5      e   Ub	  U" UU5        URK                  5       n[:        R\                  RM                  UU
5      nURN                  (       a;  UR)                  5       nUR+                  U5        URI                  U5      nU" UU5        U$ )aX  Test routine for a layer with a single input and single output.

Args:
  layer_cls: Layer class object.
  kwargs: Optional dictionary of keyword arguments for instantiating the
    layer.
  input_shape: Input shape tuple.
  input_dtype: Data type of the input data.
  input_data: Numpy array of input data.
  expected_output: Numpy array of the expected output.
  expected_output_dtype: Data type expected for the output.
  expected_output_shape: Shape tuple for the expected shape of the output.
  validate_training: Whether to attempt to validate training on this layer.
    This might be set to False for non-differentiable layers that output
    string or integer values.
  adapt_data: Optional data for an 'adapt' call. If None, adapt() will not
    be tested for this layer. This is only relevant for PreprocessingLayers.
  custom_objects: Optional dictionary mapping name strings to custom objects
    in the layer class. This is helpful for testing custom layers.
  test_harness: The Tensorflow test, if any, that this function is being
    called in.
  supports_masking: Optional boolean to check the `supports_masking`
    property of the layer. If None, the check will not be performed.

Returns:
  The output data (Numpy array) returned by the layer, for additional
  checks to be done by the calling code.

Raises:
  ValueError: if `input_shape is None`.
Nzinput_shape is Noner,         
      float      ?When testing layer z%, the `supports_masking` property is zbut expected to be .
Full kwargs: weights)shaper%   , for input z, found output dtype= but expected to find c                   > [        U 5      [        U5      :w  a)  [        STR                  < ST< SU< SU < ST< 3
5      e[        X5       H  u  p#[	        U[
        R                  R                  R                  5      (       a  UR                  n[	        U[
        R                  R                  R                  5      (       a  UR                  nUc  M  X#:w  d  M  [        STR                  < ST< SU< SU < ST< 3
5      e   g)zFAsserts that the output shape from the layer matches the actual
shape.rB   rF   , found output_shape=rG   rC   N)
lenAssertionError__name__zip
isinstancetfcompatr:   	Dimensionvalue)r   r   expected_dim
actual_dimkwargs	layer_clsr7   s       r   assert_shapes_equal'layer_test.<locals>.assert_shapes_equal   s     x=CK'  %%q&(FD  ),H(=$L,		(>(>??+11*biill&<&<=='--
'L,F$ !))1fhH  )>r   z, found output_dtype=r   mseacc)weighted_metricsrun_eagerly)r[   batch_input_shapez& **after deserialization**, for input rI   z% but expected to find inferred shape  )1
ValueErrorlist	enumerater   r(   r*   astyperE   r%   rO   as_dtypestringassertAllEqualr   assertAllCloser!   supports_maskingrK   rL   adaptget_weightsset_weightsr   
getargspec__init__r   Inputr   TensorShaper   Modeltuplecompute_output_shapeas_listcompute_output_signature
TensorSpecpredict
get_configfrom_configrD   _thread_local_datar\   compileshould_run_eagerlytrain_on_batch	__class__
SequentialaddrM   )"rV   rU   r1   input_dtype
input_dataexpected_outputexpected_output_dtypeexpected_output_shapevalidate_training
adapt_datacustom_objectstest_harnessrg   input_data_shaper8   eassert_equallayerrD   r6   rW   modelcomputed_output_shapecomputed_output_signatureactual_outputactual_output_shapemodel_configrecovered_modeloutputlayer_weightslayer_configrS   rT   r7   s"   ``                               @r   
layer_testr   X   s   ` 233#K,./DAy&(ii&7&71&= # 0 "))**+;<<
r?g%#J&&{3
		 && &&$ +	{{()RYY6'66L&L'66L'L \rFE 	$""&66 ""&& 	
 		
 J !G	g J)))*<*<==#y#F# 	;qr?+>AaA}}Q00 ""a %

 
	
, (BNN+@A177K LLAE!""2>>+#>?GGI !& > >
K;! MM*-M'---/BC1779LM &&-*=*== ""##)//

 
	
 "]O4 ##%Lll..|^LO}}##%##G, ((4V]+ 	  Qa)))5MM"'.0	   MM)UeWMEZ7 ##%L(3L$%OO''5E JE	IIfllQRDE	IIe	m$MM*-M'--$'2% j #z)$ "**+-
 %$ "]O4 ##%L''33nO }}##%##G, ((4V]+ r   c              #      #    [         R                  n U [         l        U v   U[         l        g! U[         l        f = f7f)zProvides a scope within which the model type to test is equal to `value`.

The model type gets restored to its original value upon exiting the scope.

Args:
   value: model type value

Yields:
  The provided value.
N)rx   
model_typerR   previous_values     r   model_type_scoper   b  s9      (22N7(-% )7%%   ?/ ?<?c              #      #    [         R                  n U [         l        U v   U[         l        g! U[         l        f = f7f)a"  Provides a scope within which we compile models to run eagerly or not.

The boolean gets restored to its original value upon exiting the scope.

Args:
   value: Bool specifying if we should run models eagerly in the active
     test. Should be True or False.

Yields:
  The provided value.
N)rx   r\   r   s     r   run_eagerly_scoper   w  s9      (33N8).& *8&&r   c                      [         R                  c  [        S5      e[         R                  =(       a    [        R                  " 5       $ )z@Returns whether the models we are testing should be run eagerly.ziCannot call `should_run_eagerly()` outside of a `run_eagerly_scope()` or `run_all_keras_modes` decorator.)rx   r\   r_   rO   executing_eagerlyr^   r   r   rz   rz     s<    %%-
 	
 ))Db.B.B.DDr   c              +      #    [         R                  n[         R                  n U [         l        U[         l        Sv   U[         l        U[         l        g! U[         l        U[         l        f = f7f)a!  Provides a scope within which the savde model format to test is `value`.

The saved model format gets restored to its original value upon exiting the
scope.

Args:
   value: saved model format value
   **kwargs: optional kwargs to pass to the save function.

Yields:
  The provided value.
N)rx   saved_model_formatsave_kwargs)rR   rU   previous_formatprevious_kwargss       r   saved_model_format_scoper     sb      );;O(44O905-)/& 1@-)8& 1@-)8&s   !A0A A0A--A0c                  Z    [         R                  c  [        S5      e[         R                  $ )NzzCannot call `get_save_format()` outside of a `saved_model_format_scope()` or `run_with_all_saved_model_formats` decorator.)rx   r   r_   r^   r   r   get_save_formatr     s.    ,,4<
 	

 000r   c                  l    [         R                  c  [        S5      e[         R                  =(       d    0 $ )NzzCannot call `get_save_kwargs()` outside of a `saved_model_format_scope()` or `run_with_all_saved_model_formats` decorator.)rx   r   r_   r^   r   r   get_save_kwargsr     s3    %%-<
 	

 ))/R/r   c                  Z    [         R                  c  [        S5      e[         R                  $ )z*Gets the model type that should be tested.ziCannot call `get_model_type()` outside of a `model_type_scope()` or `run_with_all_model_types` decorator.)rx   r   r_   r^   r   r   get_model_typer     s.    $$,
 	
 (((r   c                 ,   [         R                  " 5       nU(       a&  UR                  [        R                  " U SUS95        O$UR                  [        R                  " U SS95        US:X  a  SOSnUR                  [        R                  " XS95        U$ )Nrelu)
activation	input_dimr   r<   sigmoidsoftmax)r   r}   r~   r   Dense)
num_hiddenr2   r   r   r   s        r   get_small_sequential_mlpr     sp    E		LL)L	
 			&,,zf=>)Q.IJ	IIfll;>?Lr   c                     [         R                  " U4S9n[         R                  " U SS9" U5      nUS:X  a  SOSn[         R                  " XS9" U5      n[        R                  " X45      $ )N)rE   r   r   r<   r   r   )r   rm   r   r   ro   )r   r2   r   inputsoutputsr   s         r   get_small_functional_mlpr     sW    \\-Fll:&9&AG)Q.IJll;>wGG<<((r   c                   D   ^  \ rS rSrSr SU 4S jjrS rU 4S jrSrU =r	$ )SmallSubclassMLPi  z!A subclass model based small MLP.c                   > [         TU ]  " SSS0UD6  Xl        X l        X0l        X@l        [        R                  " USS9U l        US:X  a  SOSn[        R                  " X&S9U l	        U R
                  (       a  [        R                  " S5      U l        U R                  (       a  [        R                  " S	S
9U l        g g )Nname
test_modelr   r   r<   r   r   rA   )axisr^   )superrl   r   r2   use_bnuse_dpr   r   layer_alayer_bDropoutdpBatchNormalizationbn)selfr   r2   r   r   rU   r   r|   s          r   rl   SmallSubclassMLP.__init__  s     	5l5f5$&||J6B"-"2Y	
||KG;;nnS)DG;;//R8DG r   c                     U R                  U5      nU R                  (       a  U R                  U5      nU R                  (       a  U R	                  U5      nU R                  U5      $ r   )r   r   r   r   r   r   r   r   rU   r7   s       r   callSmallSubclassMLP.call  sF    LL ;;
A;;
A||Ar   c                    > [         TU ]  5       nUR                  U R                  U R                  U R
                  U R                  S.5        U$ )N)r   r2   r   r   )r   rv   updater   r2   r   r   )r   configr|   s     r   rv   SmallSubclassMLP.get_config  sF    #%"oo#//++++		
 r   )r   r   r   r   r2   r   r   r   )FF)
rL   
__module____qualname____firstlineno____doc__rl   r   rv   __static_attributes____classcell__r|   s   @r   r   r     s     + =B9"
 
r   r   c                   8   ^  \ rS rSrSrU 4S jrS rS rSrU =r	$ )_SmallSubclassMLPCustomBuildi  z;A subclass model small MLP that uses a custom build method.c                 V   > [         TU ]  5         S U l        S U l        Xl        X l        g r   )r   rl   r   r   r   r2   )r   r   r2   r|   s      r   rl   %_SmallSubclassMLPCustomBuild.__init__  s'    $&r   c                     [         R                  " U R                  SS9U l        U R                  S:X  a  SOSn[         R                  " U R                  US9U l        g )Nr   r   r<   r   r   )r   r   r   r   r2   r   )r   r1   r   s      r   build"_SmallSubclassMLPCustomBuild.build  sD    ||DOOG"&"2"2a"7YY
||D$4$4Lr   c                 F    U R                  U5      nU R                  U5      $ r   )r   r   r   s       r   r   !_SmallSubclassMLPCustomBuild.call   s    LL ||Ar   )r   r   r2   r   
rL   r   r   r   r   rl   r   r   r   r   r   s   @r   r   r     s    E'M
 r   r   c                     [        X5      $ r   )r   r   r2   s     r   get_small_subclass_mlpr   %  s    J44r   c                     [        X5      $ r   )r   r   s     r   (get_small_subclass_mlp_with_custom_buildr   )  s    '
@@r   c                     [        5       nUS:X  a  [        X5      $ US:X  a  [        X5      $ US:X  a  [        XU5      $ US:X  a  [	        XU5      $ [        SU 35      e)z@Get a small mlp of the model type specified by `get_model_type`.subclasssubclass_custom_build
sequential
functionalUnknown model type )r   r   r   r   r   r_   )r   r2   r   r   s       r   get_small_mlpr   -  sn    !JZ%j>>,,7
PP\!'
KK\!'
KK
*:,7
88r   c                   >   ^  \ rS rSrSrU 4S jrS rS rS rSr	U =r
$ )_SubclassModeli;  zA TF-Keras subclass model.c                    > UR                  SS5      n[        TU ]  " U0 UD6  [        U5       H   u  pV[	        X R                  U5      U5        M"     [        U5      U l        Ub  U R                  U5        gg)zInstantiate a model.

Args:
  model_layers: a list of layers to be added to the model.
  *args: Model's args
  **kwargs: Model's keyword args, at most one of input_tensor -> the
    input tensor required for ragged/sparse input.
input_tensorN)	popr   rl   ra   setattr_layer_name_for_irJ   
num_layers_set_inputs)r   model_layersargsrU   r   r8   r   r|   s          r   rl   _SubclassModel.__init__>  sv     ND1$)&) ",/HAD003U; 0 l+V$ r   c                     SU 3$ )Nr   r^   )r   r8   s     r   r    _SubclassModel._layer_name_for_iT  s    qc{r   c                     Un[        U R                  5       H%  n[        X R                  U5      5      nU" U5      nM'     U$ r   )r-   r   getattrr   )r   r   rU   r7   r8   r   s         r   r   _SubclassModel.callW  s?    t'AD"8"8";<EaA ( r   c                     [         er   )NotImplementedError)r   s    r   rv   _SubclassModel.get_config^  s
     "!r   )r   )rL   r   r   r   r   rl   r   r   rv   r   r   r   s   @r   r   r   ;  s    $%," "r   r   c                   8   ^  \ rS rSrSrU 4S jrS rS rSrU =r	$ )_SubclassModelCustomBuildid  z:A TF-Keras subclass model that uses a custom build method.c                 @   > [         TU ]  " U0 UD6  S U l        Xl        g r   )r   rl   
all_layers_layer_generating_func)r   layer_generating_funcr   rU   r|   s       r   rl   "_SubclassModelCustomBuild.__init__g  s"    $)&)&;#r   c                 d    / nU R                  5        H  nUR                  U5        M     X l        g r   )r
  appendr	  )r   r1   r   r   s       r   r   _SubclassModelCustomBuild.buildl  s-    002E& 3&r   c                 @    UnU R                    H  nU" U5      nM     U$ r   )r	  )r   r   rU   r7   r   s        r   r   _SubclassModelCustomBuild.callr  s#    __EaA %r   )r
  r	  r   r   s   @r   r  r  d  s    D<
' r   r  c           	      F  ^  Uc
  [        5       nUS:X  a1  SnU(       d  U(       a  [        R                  " UUUUS9n[        T X7S9$ US:X  a  U 4S jn[	        XS9$ US:X  a]  [
        R                  " US9n	U(       a&  U	R                  [        R                  " UUUUS	95        T  H  n
U	R                  U
5        M     U	$ US
:X  aQ  U(       d  [        S5      e[        R                  " UUUUS9nUnT  H  n
U
" U5      nM     [
        R                  " X{US9$ [        SU 35      e)a  Builds a model from a sequence of layers.

Args:
  model_layers: The layers used to build the network.
  input_shape: Shape tuple of the input or 'TensorShape' instance.
  input_dtype: Datatype of the input.
  name: Name for the model.
  input_ragged: Boolean, whether the input data is a ragged tensor.
  input_sparse: Boolean, whether the input data is a sparse tensor.
  model_type: One of "subclass", "subclass_custom_build", "sequential", or
    "functional". When None, defaults to `get_model_type`.

Returns:
  A TF-Keras model.
Nr   )rE   r%   raggedsparse)r   r   r   c                     > T $ r   r^   )r   s   r   <lambda>'get_model_from_layers.<locals>.<lambda>  s    r   r   r   )r1   r%   r  r  r   zACannot create a functional model from layers with no input shape.r   )r   r   rm   r   r  r   r}   r~   
InputLayerr_   ro   )r   r1   r   r   input_raggedinput_sparser   r   r  r   r   r   s   `           r   get_model_from_layersr  y  s>   0 #%
Z<\\!!##	F lKK,, 4()>JJ\!!!t,II!! +%''	 "EIIe "\!  	
 !EGnG "||F$77
*:,7
88r   c                        \ rS rSrS rS rSrg)Biasi  c                 0    U R                  SSSS9U l        g )Nbias)r<   r+   )initializer)
add_weightr   r   r1   s     r   r   
Bias.build  s    OOFDgOF	r   c                     XR                   -   $ r   r   )r   r   s     r   r   	Bias.call  s    		!!r   r&  N)rL   r   r   r   r   r   r   r^   r   r   r  r    s    G"r   r  c                   <   ^  \ rS rSrSr   SU 4S jjrS rSrU =r$ )_MultiIOSubclassModeli  z!Multi IO TF-Keras subclass model.c                 P   > [         TU ]  US9  X0l        Xl        X l        X@l        g )Nr  )r   rl   _shared_input_branch	_branch_a	_branch_b_shared_output_branch)r   branch_abranch_bshared_input_branchshared_output_branchr   r|   s         r   rl   _MultiIOSubclassModel.__init__  s+     	d#$7!!!%9"r   c                 z   U R                   (       a   U R                    H  nU" U5      nM     UnUnO$[        U[        5      (       a  US   nUS   nOUu  pEU R                   H  nU" U5      nM     U R                   H  nU" U5      nM     XE/nU R
                  (       a  U R
                   H  nU" U5      nM     U$ )Ninput_1input_2)r+  rN   dictr,  r-  r.  r   r   rU   r   aboutss          r   r   _MultiIOSubclassModel.call  s    $$22v 3AA%%y!Ay!ADA^^EaA $^^EaA $v%%33T{ 4 r   )r,  r-  r+  r.  )NNN)	rL   r   r   r   r   rl   r   r   r   r   s   @r   r)  r)    s     + !!: r   r)  c                   @   ^  \ rS rSrSr  SU 4S jjrS rS rSrU =r	$ ) _MultiIOSubclassModelCustomBuildi  zAMulti IO TF-Keras subclass model that uses a custom build method.c                    > [         TU ]  5         X0l        Xl        X l        X@l        S U l        S U l        S U l        S U l	        g r   )
r   rl   _shared_input_branch_func_branch_a_func_branch_b_func_shared_output_branch_funcr+  r,  r-  r.  )r   branch_a_funcbranch_b_funcshared_input_branch_funcshared_output_branch_funcr|   s        r   rl   )_MultiIOSubclassModelCustomBuild.__init__  sF     	)A&++*C'$(!%)"r   c                    U R                  5       (       a  U R                  5       U l        U R                  5       U l        U R	                  5       U l        U R                  5       (       a  U R                  5       U l        g g r   )r@  r+  rA  r,  rB  r-  rC  r.  r#  s     r   r   &_MultiIOSubclassModelCustomBuild.build  sg    ))++(,(F(F(HD%,,.,,.**,,)-)H)H)JD& -r   c                 :   U R                   (       a   U R                    H  nU" U5      nM     UnUnOUu  pEU R                   H  nU" U5      nM     U R                   H  nU" U5      nM     XE4nU R                  (       a  U R                   H  nU" U5      nM     U$ r   )r+  r,  r-  r.  r8  s          r   r   %_MultiIOSubclassModelCustomBuild.call  s    $$22v 3AADA^^EaA $^^EaA $t%%33T{ 4 r   )r,  rA  r-  rB  r+  r@  r.  rC  NNr   r   s   @r   r>  r>    s#    K "&"&*$K r   r>  c                   ^ ^^^ T(       a  TS   nTSS mOT S   TS   4nT SS m TSS m[        5       nUS:X  a  [        T TTT5      $ US:X  a  [        U 4S jU4S jU4S jU4S	 j5      $ US
:X  a  [        S5      eUS:X  av  T(       a  UnT H  nU" U5      nM     UnUn	OUu  pT  H  nU" U5      nM     T H  nU" U	5      n	M     X4n
T(       a  T H  nU" U
5      n
M     [        R
                  " XJ5      $ [        SU 35      e)a|  Builds a multi-io model that contains two branches.

The produced model will be of the type specified by `get_model_type`.

To build a two-input, two-output model:
  Specify a list of layers for branch a and branch b, but do not specify any
  shared input branch or shared output branch. The resulting model will
  apply each branch to a different input, to produce two outputs.

  The first value in branch_a must be the TF-Keras 'Input' layer for branch
  a, and the first value in branch_b must be the TF-Keras 'Input' layer for
  branch b.

  example usage:
  ```
  branch_a = [Input(shape=(2,), name='a'), Dense(), Dense()]
  branch_b = [Input(shape=(3,), name='b'), Dense(), Dense()]

  model = get_multi_io_model(branch_a, branch_b)
  ```

To build a two-input, one-output model:
  Specify a list of layers for branch a and branch b, and specify a
  shared output branch. The resulting model will apply
  each branch to a different input. It will then apply the shared output
  branch to a tuple containing the intermediate outputs of each branch,
  to produce a single output. The first layer in the shared_output_branch
  must be able to merge a tuple of two tensors.

  The first value in branch_a must be the TF-Keras 'Input' layer for branch
  a, and the first value in branch_b must be the TF-Keras 'Input' layer for
  branch b.

  example usage:
  ```
  input_branch_a = [Input(shape=(2,), name='a'), Dense(), Dense()]
  input_branch_b = [Input(shape=(3,), name='b'), Dense(), Dense()]
  shared_output_branch = [Concatenate(), Dense(), Dense()]

  model = get_multi_io_model(input_branch_a, input_branch_b,
                             shared_output_branch=shared_output_branch)
  ```
To build a one-input, two-output model:
  Specify a list of layers for branch a and branch b, and specify a
  shared input branch. The resulting model will take one input, and apply
  the shared input branch to it. It will then respectively apply each branch
  to that intermediate result in parallel, to produce two outputs.

  The first value in the shared_input_branch must be the TF-Keras 'Input'
  layer for the whole model. Branch a and branch b should not contain any
  Input layers.

  example usage:
  ```
  shared_input_branch = [Input(shape=(2,), name='in'), Dense(), Dense()]
  output_branch_a = [Dense(), Dense()]
  output_branch_b = [Dense(), Dense()]


  model = get_multi_io_model(output__branch_a, output_branch_b,
                             shared_input_branch=shared_input_branch)
  ```

Args:
  branch_a: A sequence of layers for branch a of the model.
  branch_b: A sequence of layers for branch b of the model.
  shared_input_branch: An optional sequence of layers to apply to a single
    input, before applying both branches to that intermediate result. If
    set, the model will take only one input instead of two. Defaults to
    `None`.
  shared_output_branch: An optional sequence of layers to merge the
    intermediate results produced by branch a and branch b. If set,
    the model will produce only one output instead of two.
    Defaults to `None`.

Returns:
  A multi-io model of the type specified by `get_model_type`, specified
  by the different branches.
r   r<   Nr   r   c                     > T $ r   r^   )r/  s   r   r  $get_multi_io_model.<locals>.<lambda>      Xr   c                     > T $ r   r^   )r0  s   r   r  rP    rQ  r   c                     > T $ r   r^   )r1  s   r   r  rP    s    (r   c                     > T $ r   r^   )r2  s   r   r  rP    s    )r   r   z>Cannot use `get_multi_io_model` to construct sequential modelsr   r   )r   r)  r>  r_   r   ro   )r/  r0  r1  r2  r   r   a_and_br   r9  r:  r   s   ````       r   get_multi_io_modelrV  +  sK   f $Q'1!"5!hqk)AB<AB<!JZ$h 35I
 	
 ,,/()	
 	
 \!L
 	
 \!G,. -AADAEaA EaA $-. . ||F,,
*:,7
88r   )r   r   r	   r
   r   r   sgdc           
           [         U    " S0 UD6$ ! [         a7    [        SR                  U [	        [         R                  5       5      5      5      ef = f)a  Get the v2 optimizer requested.

This is only necessary until v2 are the default, as we are testing in Eager,
and Eager + v1 optimizers fail tests. When we are in v2, the strings alone
should be sufficient, and this mapping can theoretically be removed.

Args:
  name: string name of TF-Keras v2 optimizer.
  **kwargs: any kwargs to pass to the optimizer constructor.

Returns:
  Initialized TF-Keras v2 optimizer.

Raises:
  ValueError: if an unknown name was passed.
z;Could not find requested v2 optimizer: {}
Valid choices: {}r^   )_V2_OPTIMIZER_MAPKeyErrorr_   formatr`   keys)r   rU   s     r   get_v2_optimizerr]    sV    "
 &000 
$$*F46G6L6L6N1O$P
 	

s
    AAc                     [         R                  R                  R                  5       (       d  [         R                  " 5       (       a  U  Vs/ s H  o"S-   PM	     sn$ U  Vs/ s H
  o"U-   S-   PM     sn$ s  snf s  snf )zEReturns expected metric variable names given names and prefix/suffix.z:0)rO   __internal__tf2enabledr   )	var_namesname_suffixns      r   "get_expected_metric_variable_namesre    sd    	""$$(<(<(>(>"+,)QD),,,56IqOd"I66 -6s   A5!A:c                     [        U S5      $ )z=Decorator for enabling the layer V2 dtype behavior on a test.T_set_v2_dtype_behaviorfns    r   enable_v2_dtype_behaviorrk    s    !"d++r   c                     [        U S5      $ )z>Decorator for disabling the layer V2 dtype behavior on a test.Frg  ri  s    r   disable_v2_dtype_behaviorrm    s    !"e,,r   c                    ^ ^ [         R                  " T 5      UU 4S j5       n[        R                  R                  R                  T U5      $ )zCReturns version of 'fn' that runs with v2 dtype behavior on or off.c                     > [         R                  nT[         l         T" U 0 UD6U[         l        $ ! U[         l        f = fr   )r   V2_DTYPE_BEHAVIOR)r   rU   v2_dtype_behaviorra  rj  s      r   wrapper'_set_v2_dtype_behavior.<locals>.wrapper  s?    ,>>-4*	Ct&v&1B.1B.s   1 >)	functoolswrapsrO   r_  	decoratormake_decorator)rj  ra  rr  s   `` r   rh  rh    sA     __RC C ??$$33B@@r   c              #      #    U (       a&  [         R                  R                  5       (       a  SnOSn[         R                  " U5         Sv   SSS5        g! , (       d  f       g= f7f)&Uses gpu when requested and available.z/device:GPU:0z/device:CPU:0N)rO   testis_gpu_availabledevice)should_use_gpudevs     r   r|  r|    s=      "''2244	3 
s   AA'A	A'
A$ A'c               #   Z   #    [        SS9   Sv   SSS5        g! , (       d  f       g= f7f)ry  T)r}  N)r|  r^   r   r   use_gpur    s      
t	$ 
%	$	$s   
+	+
(+c                    ^ ^^ UU U4S jnU$ )a  Generate class-level decorator from given method-level decorator.

It is expected for the given decorator to take some arguments and return
a method that is then called on the test method to produce a decorated
method.

Args:
  decorator: The decorator to apply.
  *args: Positional arguments
  **kwargs: Keyword arguments
Returns: Function that will decorate a given classes test methods with the
  decorator.
c           
         > [        U 5       HX  n[        X5      n[        U5      (       d  M   UR                  S5      (       d  M8  US:w  d  M@  [	        XT" T0 TD6" U5      5        MZ     U $ )z-Apply decorator to all test methods in class.rz  test_session)dirr  callable
startswithr   )clsr   rR   r   rv  rU   s      r   all_test_methods_impl3for_all_test_methods.<locals>.all_test_methods_impl  s[    HDC&EOOF++^+9d#=f#=e#DE  
r   r^   )rv  r   rU   r  s   ``` r   for_all_test_methodsr    s    
 ! r   c                     S nU$ )a  Execute test with TensorFloat-32 disabled.

While almost every real-world deep learning model runs fine with
TensorFloat-32, many tests use assertAllClose or similar methods.
TensorFloat-32 matmuls typically will cause such methods to fail with the
default tolerances.

Args:
  description: A description used for documentation purposes, describing why
    the test requires TensorFloat-32 to be disabled.

Returns:
  Decorator which runs a test with TensorFloat-32 disabled.
c                 F   ^  [         R                  " T 5      U 4S j5       nU$ )Nc                 p  > [         R                  R                  R                  5       n [         R                  R                  R	                  S5        T" U /UQ70 UD6  [         R                  R                  R	                  U5        g ! [         R                  R                  R	                  U5        f = f)NF)rO   r   experimental!tensor_float_32_execution_enabled enable_tensor_float_32_execution)r   r   rU   allowedfs       r   	decoratedArun_without_tensor_float_32.<locals>.decorator.<locals>.decorated;  s|    ii,,NNPGQ		&&GGN$(((		&&GGP		&&GGPs   5B
 
+B5)rt  ru  )r  r  s   ` r   rv  .run_without_tensor_float_32.<locals>.decorator:  s(    			Q 
	Q r   r^   )descriptionrv  s     r   run_without_tensor_float_32r  *  s     
 r   c                 "    [        [        U 5      $ )z:Execute all tests in a class with TensorFloat-32 disabled.)r  r  )r  s    r   run_all_without_tensor_float_32r  J  s       ;[IIr   c                    ^ ^^ [         R                  R                  R                  5       (       + mSmUU U4S jnT b  U" T 5      $ U$ )aA  Execute the decorated test only if running in v2 mode.

This function is intended to be applied to tests that exercise v2 only
functionality. If the test is run in v1 mode it will simply be skipped.

See go/tf-test-decorator-cheatsheet for the decorators to use in different
v1/v2/eager/graph combinations.

Args:
  obj: function to be annotated. If None, return a
    decorator the can be applied to a function or class. If `obj` is not
    None, return the decorator applied to `obj`.

Returns:
  Returns a decorator that will conditionally skip the decorated test
  method.
z#Test is only compatible with TF v2.c                    >^  [         R                  " T 5      (       a  [        R                  " TTS9" T5      $ UU U4S jnU$ )N)	conditionreasonc                 L   > T(       a  U R                  T5        T" U /UQ70 UD6$ r   )skipTest)r   r   rU   r  r  r  s      r   r  1run_v2_only.<locals>.decorator.<locals>.decoratedj  s'    f%T+D+F++r   )r   isclassunittestskipIf)r  r  r  objr  s   ` r   rv  run_v2_only.<locals>.decoratorf  s7    a  ??YvFsKK	,
 r   )rO   r_  r`  ra  )r  rv  r  r  s   ` @@r   run_v2_onlyr  Q  sA    $ OO''//11I2F	 ~r   c                  r   S n/ n[        U R                  5       US9 H@  u  p4[        U[        5      (       d  U/nUR	                  U Vs/ s H  oSU4PM     sn5        MB     [
        R                  " U6  Vs/ s H  n[        R                  " U5      PM     nn/ nU GH  n[        U[        R                  5      (       d   eSR                  UR                  5        VVs/ s Hn  u  p5SR                  SR                  [        [        R                  U5      5      SR                  [        [        R                  [        U5      5      5      5      PMp     snn5      n	UR	                  [        R                  " [        UR                  5       5      SSU	 34/-   5      5        GM     U$ s  snf s  snf s  snnf )a  Generate combinations based on its keyword arguments using combine().

This function calls combine() and appends a testcase name to the list of
dictionaries returned. The 'testcase_name' key is a required for named
parameterized tests.

Args:
  **kwargs: keyword arguments of form `option=[possibilities, ...]` or
    `option=the_only_possibility`.

Returns:
  a list of dictionaries for each combination. Keys in the dictionaries are
  the keyword argument names.  Each key has one value - one of the
  corresponding keyword argument values.
c                     U S   $ )Nr   r^   )ks    r   r  :generate_combinations_with_testcase_name.<locals>.<lambda>  s    AaDr   )key z_{}_{}testcase_name_test)sorteditemsrN   r`   r  	itertoolsproductcollectionsOrderedDictjoinr[  filterstrisalnum)
rU   sort_by_keycombinationsr  valuesrR   resultnamed_combinationscombinationr   s
             r   (generate_combinations_with_testcase_namer  w  s     !KLflln+>&$''XFv>ve5\v>? ?  ''66F 	'6   #+{'>'>????ww #."3"3"5
 #6JC	 GGF3;;45GGF3;;E
;< #6
 	!!##[&&()otf~-N,OO	
 $" 1 ?s   
F)
7 F. A5F3r   )NNNNNNNTNNNN)NNNNNNrM  )r  )ar   r  
contextlibrt  r  	threadingr  numpyr   tensorflow.compat.v2rP   v2rO   tf_keras.srcr   r   r   tf_keras.src.enginer   tf_keras.src.optimizers.legacyr   adadelta_v2r   
adagrad_v2r	   adam_v2r
   	adamax_v2r   gradient_descent_v2r   nadam_v2r   
rmsprop_v2tf_keras.src.utilsr   r   tensorflow.python.frameworkr   tf_test_utils tensorflow.python.util.tf_exportr   r   r!   r9   disable_cudnn_autotuner   localrx   r   r\   r   r   contextmanagerr   r   rz   r   r   r   r   r   r   ro   r   r   r   r   r   r   r  r  Layerr  r)  r>  rV  AdadeltaAdagradAdamAdamaxNadamRMSpropSGDrY  r]  re  rk  rm  rh  r|  r  r  r  r  r  r  r^   r   r   <module>r     s   +        ! !     0 B @ : > R < @ , ) :4G
 HL> 3;%% ~ & <~B __&  $  !%  (,  %!%   7 7( 8 8*	E 9 9210	)
)&v|| &R6<< (5A9&"V\\ &"R . 	I9X"6<< "'FLL 'T1v|| 1j HLD9P $$!!LL^^!!"" 
47,
-
A    !>@J#L-r   