
    0h$                         d Z ddlZddlZddlZddlZddlZddlmc m	Z
 ddlmZ ddlmZ ddlmZ  ed      dd       Z	 	 ddZd	 Zd
 Zd Zd Zd ZddZ	 	 	 	 	 	 ddZ	 ddZd Zd Zd Z G d d      Z ed      	 dd       Zd Z y)z/Utilities related to layer/model functionality.    N)initializers)io_utils)keras_exportzkeras.utils.get_source_inputsc                    t        | d      s| S ||r| j                  \  }}}|j                  s| gS |j                  |   }|j                  r)t        j
                  j                  |j                        S g }|j                         D ]A  \  }}}} t        | ||      }|D ](  t        fd|D              s|j                         * C |S )a  Returns the list of input tensors necessary to compute `tensor`.

    Output will always be a list of tensors
    (potentially with 1 element).

    Args:
        tensor: The tensor to start from.
        layer: Origin layer of the tensor. Will be
            determined via tensor._keras_history if not provided.
        node_index: Origin node index of the tensor.

    Returns:
        List of input tensors.
    _keras_historyc              3   &   K   | ]  }|u 
 y wN ).0txs     X/var/www/html/engine/venv/lib/python3.12/site-packages/tf_keras/src/utils/layer_utils.py	<genexpr>z$get_source_inputs.<locals>.<genexpr>C   s     >!1A:>s   )hasattrr   _inbound_nodesis_inputtfnestflatteninput_tensorsiterate_inboundget_source_inputsallappend)tensorlayer
node_index_nodesource_tensorsprevious_sourcesr   s          @r   r   r   !   s      6+,}
%44z1x##J/==77??4#5#566N040D0D0F 1,z1f#4VUJ#O ) 1A>~>>&--a011 "!    c                     |r| y|rt        |       ryt        | t              r| |v ry|rdnd}||rdndz  }|d| z  }|rd| d}nd}t        d| d	| d
| d| d|  
      )z0Validates the correctness of a string-based arg.Nz`None`,  za `Callable`, z or one of the following values: zIf restoring a model and `z` is a custom callable, please ensure the callable is registered as a custom object. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details. zUnkown value for `z` argument of layer z. zAllowed values are: z. Received: )callable
isinstancestr
ValueError)
input_dataallowable_strings
layer_namearg_name
allow_noneallow_callablesallowed_argscallable_notes           r   validate_string_argr1   H   s     j(	Xj1	J	$7H)H%/zRO(C:;L:MNN,XJ 7? ?  M 
*>zl"o1,|l
 	
r"   c                    | D ci c]  }t        |      | c}j                         }|D cg c]  }t        |d      s| }}|D cg c]  }|j                  j	                          }}|D cg c]  }|D cg c]  }|dn|
 c} }}}t        t        d |D                    S c c}w c c}w c c}w c c}w c c}}w )zCount the total number of scalars composing the weights.

    Args:
        weights: An iterable containing the weights on which to compute params

    Returns:
        The total number of scalars composing the weights
    shaper   c              3   F   K   | ]  }t        j                  |        y wr	   )npprod)r   ps     r   r   zcount_params.<locals>.<genexpr>|   s     B!2771:Bs   !)idvaluesr   r3   as_listintsum)weightswunique_weightsweight_shapesw_istandardized_weight_shapess         r   count_paramsrC   l   s     )001beQh0779N!/GA71g3FaGNG0>?1QWW__&?M?:G"56a0scks	"0" " sB'ABBCC 1G?0"s-   B*B/B/	!B41	B>:B9B>9B>c                 \   | D ci c]  }t        |      | c}j                         }d}|D ]w  }t        |d      sd|j                  j	                         v r-t        j                  |j                  j	                               }|j                  j                  }|||z  z  }y |S c c}w )zCalculate the memory footprint for weights based on their dtypes.

    Args:
        weights: An iterable contains the weights to compute weight size.

    Returns:
        The total memory size (in Bytes) of the weights.
    r   r3   N)	r8   r9   r   r3   r:   r5   r6   dtypesize)r=   r>   r?   total_memory_sizeweight_shapeper_param_sizes         r   weight_memory_sizerJ      s     )001beQh0779N ;q'"QWW__&&wwqww01\N::;  1s   B)c                    | D ci c]  }t        |      | c}j                         }d}d}i }|D ]O  }t        |d      st        |t        j
                  j                  j                        s@|j                  }t        t        t        |j                                    }t        j
                  j                  j                  |v r3|j                  t        j
                  j                  j                         t        |      }|j!                  |d      \  }}	t#        j$                  |j&                  j)                               }
|j*                  j,                  }||
z  }|	|
|z  z  }	||	f||<   ||
z  }||
|z  z  }R |||fS c c}w )a2  Group and calculate DTensor based weights memory size.

    Since DTensor weights can be sharded across multiple device, the result
    will be grouped by the layout/sharding spec for the variables, so that
    the accurate per-device memory size can be calculated.

    Args:
        weights: An iterable contains the weights to compute weight size.

    Returns:
        total_weight_count, total_memory_size and per_sharing_spec_result which
        is a dict with normalized layout spec as key and tuple of weight count
        and weight size as value.
    r   r3   )r   r   )r8   r9   r   r&   r   experimentaldtensor	DVariablelayoutlistsortedsetsharding_specs	UNSHARDEDremovetuplegetr5   r6   r3   r:   rE   rF   )r=   r>   r?   total_weight_countrG   per_sharing_spec_resultrO   reduced_sharding_specweight_countmemory_sizereduced_weight_shaperI   s               r   dtensor_variable_summaryr^      s    )001beQh0779N  Cq'"!R__44>>?
 !%VC0E0E,F%G H??"",,0EE!(()@)@)J)JK %&; <$;$?$?!6%
!k  "wwqww'89,,+n<<:
 56 	221NBB7C8 02IIIA 1s   F	c                    t        | dd       | j                  j                         }n;t        | d      r-t        | j                  d      r| j                  j
                  }nd }|rt        | j                        \  }}}d}t        |j                               D ]  }||   \  }	}
t        |      dk(  r ||	 d| dt        |
       d       |
}nWt        j                  |D cg c]  }|j                  |       c}      }|
|z  } ||	 d| dt        |
       d| d	| d

       ||z  }  |dt        |               |dj                  ||z                |d|z         y y c c}w )N_layout_mapdistribute_strategy_meshr   z / z	 params (z) are fully replicatedz) are sharded based on spec 'z' and across z	 devices.z!Overall per device memory usage: zOverall sharding factor: {:.2f}r   )getattrr`   get_default_meshr   ra   rb   r^   r=   rQ   keyslenreadable_memory_sizer5   r6   dim_sizeformat)modelprint_fnline_lengthmeshrX   rG   rY   total_per_device_memory_sizesharding_speccountr\   per_device_sizessharding_factors                 r   print_dtensor_variable_summaryrt      s   umT*6  113	-	.7!!74 ((.. 
 %U]]3		
#'($#$;$@$@$BC 	<M!8!GE;=!Q&gS!3 4 5,[9: ;++
 #."$''/<=!T]]1%=# #."?gS!3 4 5,[9: ;  -mO;L M  )O;()	<* 	/#$@ABD	
 	-44!$@@	

 	{"#K $ >s   $E*
c                     g d}d}|D ]#  }| |z  dk  rdj                  | |      c S | |z  } % dj                  | |d         S )z<Convert the weight memory size (Bytes) to a readable string.)ByteKBMBGBTBPBi      z	{:.2f} {})ri   )rJ   unitsscaleunits       r   rg   rg      sa    2EE (%)%%&8$??%'	(
 0%)<<r"   c                    |\t        |      dk7  rt        d| dt        |             t        |d   t              rt        |d   t              s%t        d|       dt        | j                        gS t        | j                        D cg c]*  \  }}t        j                  |d   |j                        r|, }}}t        | j                        D cg c]*  \  }}t        j                  |d   |j                        r|, }}}|r|st        d|       t        |      t        |      kD  rt        |      t        |      dz   gS t        |      t        |      dz   gS c c}}w c c}}w )a3  Get the layer indexes from the model based on layer names.

    The layer indexes can be used to slice the model into sub models for
    display.

    Args:
        model: `tf.keras.Model` instance.
        layer_names: a list or tuple of 2 strings, the starting layer name and
            ending layer name (both inclusive) for the result. All layers will
            be included when `None` is provided.

    Returns:
        The index value of layer based on its unique name (layer_names).
        Output will be [first_layer_index, last_layer_index + 1].
       zIlayer_range must be a list or tuple of length 2. Received: layer_range = z of length r   r|   z7layer_range should contain string type only. Received: zHPassed layer_names do not match the layer names in the model. Received: )rf   r(   r&   r'   layers	enumeraterematchnameminmax)rj   layer_rangeidxr   lower_indexupper_indexs         r   #get_layer_index_bound_by_layer_namer     s     {q !!,[[9I8JL  +a.#.jNC7
 (M+ 
 3u||$%% $ELL1C88KNEJJ/ 	K  $ELL1C88KNEJJ/ 	K  k$'
 	

 ;#k**K #k"2Q"677c+.233'
s   /E%/E+c                    t         j                  | j                  j                  dk(  rdn| j                  sdnd| j
                  j                         }g }|D ]_  }	t        |	      dkD  sFt        |	      dk(  r<t        t        j                  j                  |	d   j                              dkD  rd n||	z  }a r5| j                  D ]&  }
d}|
j                  D ]  }||v s|rd nd} r& n r7xs dxs g dd	   dk  rD cg c]  }t        |z         c}g d
}n\xs dxs g dd	   dk  rD cg c]  }t        |z         c}g d}g | j
                  j                         D ]  }	|	z  	 r'dz  j                         |j                  d       t!        | |      }dfd	 d| j"                   d        dz          |        dz         dfd	dfd	dfd	| j                  |d   |d    D ]
  }
 |
         dz         t%        | d      r+t'        | j(                        }t+        | j(                        }n*t'        | j,                        }t+        | j,                        }t'        | j.                        }t+        | j.                        }||z   } d||z    dt1        |       d        d| dt1        |       d        d| dt1        |       d        dz         t3        |        yc c}w c c}w ) a  Prints a summary of a model.

    Args:
        model: TF-Keras model instance.
        line_length: Total length of printed lines
            (e.g. set this to adapt the display to different
            terminal window sizes).
        positions: Relative or absolute positions of log elements in each line.
            If not provided, defaults to `[0.3, 0.6, 0.70, 1.]`.
        print_fn: Print function to use.
            It will be called on each line of the summary.
            You can set it to a custom function
            in order to capture the string summary.
            When `None`, uses `print` (prints to stdout).
            Defaults to `None`.
        expand_nested: Whether to expand the nested models.
            Defaults to `False`.
        show_trainable: Whether to show if a layer is trainable.
            Defaults to `False`.
        layer_range: List or tuple containing two strings,
            the starting layer name and ending layer name (both inclusive),
            indicating the range of layers to be printed in the summary. The
            strings could also be regexes instead of an exact name. In this
             case, the starting layer will be the first layer that matches
            `layer_range[0]` and the ending layer will be the last element that
            matches `layer_range[1]`. By default (`None`) all
            layers in the model are included in the summary.
    N
SequentialTr|   r   FA   )g?g333333?      ?r}   )Layer (type)Output ShapeParam #b   )g333333?g333333?gffffff?r   )r   r   r   zConnected to   	Trainablec                    | D cg c]  }t        |       }}t        |      rYd}t        t        |            D ]!  }|dkD  r	||dz
     }nd}||   }|t        |      dz
  k7  rdnd}	||z
  |	z
  }
|t        |      dz
  k7  r|
dz  }
|dk(  r|
|z  }
||   d |
 }d}|D cg c]3  }|j	                  |      dk\  r|j	                  |      t        |      z   5 }}|rt        |      }
|d |
 }|dk(  r|d|z  dz   z  }||z  }||	rd|	z  ndz  }||   |
d  ||<   |r-|t        |      dz
  k(  r|d||   t        |      z
  |z
  z  z  }|d||   t        |      z
  z  z  }$ |d|z  z  } |       t        |      rXy y c c}w c c}w )Nr$   r   r|   r   )z),z},z],z',| )r'   anyrangerf   findr   )fields	positionsnested_levelr   left_to_printlinecol	start_posend_posspacecutofffit_into_lineline_break_conditionscandidate_cutoffsrk   s                 r   	print_rowz print_summary.<locals>.print_row  s   )/0AQ00- DS/0 '?7 )#' 2I !I#C. !C	NQ$66A 9,u4#i.1,,aKF!8l*F -c 27F ; )A% 3%$))!,1 "&&q)CF2%! %
 % !23F$1'6$:M!8C,.44D%ue"4%23%7%@c"  C3y>A+=$=C9S>CI#=#LMMDC9S>CI#=>>DO'?P C,&&DTNW -   1,%s   F  8FzModel: ""r   =c                 h   	 | j                   }| j                  }| j                  j
                  }| j                  st        | dd      sd}n| j                         }|dz   |z   dz   ||g}	r|j                  | j                  rdnd	        ||       y
# t        $ r d}Y t        $ r d}Y w xY w)zPrints a summary for a single layer.

        Args:
            layer: target layer.
            nested_level: level of nesting of the layer inside its parent layer
              (e.g. 0 for a top-level layer, 1 for a nested layer).
        multiple?_is_graph_networkFz
0 (unused) ()YNN)output_shapeAttributeErrorRuntimeErrorr   	__class____name__builtrc   rC   r   	trainable)
r   r   r   r   cls_nameparamsr   r   r   show_trainables
          r   print_layer_summaryz*print_summary.<locals>.print_layer_summary  s    	 --L
 zz??++{{752Eu#M "F'')F+(3.fEMM#c:&)\2%  	&%L 	L	s   B B1$
B10B1c           
         	 | j                   }g }| j                  D ]G  }r|vr
|j                         D ]+  \  }}}}|j	                  |j
                   d| d| d       - I | j
                  }	| j                  j                  }
|	dz   |
z   dz   || j                         |g}r|j	                  | j                  rdnd        ||       y	# t        $ r d}Y w xY w)
a  Prints a summary for a single layer (including its connections).

        Args:
            layer: target layer.
            nested_level: level of nesting of the layer inside its parent layer
              (e.g. 0 for a top-level layer, 1 for a nested layer).
        r   [z][]r   r   r   r   N)
r   r   r   r   r   r   r   r   rC   r   )r   r   r   connectionsr   inbound_layerr   tensor_indexr   r   r   r   r   r   relevant_nodesr   s               r   $print_layer_summary_with_connectionsz;print_summary.<locals>.print_layer_summary_with_connections  s   	& --L (( 	D$n"< %%' ""$))*!J<r,qI	 zz??++4K("S( 	
 MM#c:&)\2=  	&%L	&s   C C C c                    r
 	| |       n	 
| |       rt        | d      r| j                  r d|dz   z  dd|z  z
  dz
  z  z   d|dz   z  z          | j                  }d}t        t        |            D ]%  }|t        |      dz
  k(  rd} ||   |dz   |       '  d|z  dd|z  z
  z  z   d|z  z          |s d|z  dd|z  z
  z  z   d|z  z          y y )	Nr   r   r|      ¯r   FTr   )r   r   r   rf   )r   r   is_nested_lastnested_layeriexpand_nestedrl   rk   print_layerr   r   sequential_likes        r   r   z"print_summary.<locals>.print_layer  s:   |40EWUH5%,,|a'(+L(881<=>)*+ !<<L"N3|,- OL)A--%)NLO\A-=~NO
 l"+L(889:$% l"q<'7789$% r"   _collected_trainable_weightszTotal params: r   r   zTrainable params: zNon-trainable params: )r   )r   F)r   	print_msgr   r   r   _nodes_by_depthr9   rf   r   r   r   keras_inputsr   r   r;   r   r   r   r   rC   r   rJ   trainable_weightsnon_trainable_weightsrg   rt   )rj   rl   r   rk   r   r   r   nodes_by_depthnodesvr   flagr   r7   
to_displaytrainable_counttrainable_memory_sizenon_trainable_countnon_trainable_memory_sizerG   r   r   r   r   r   r   s    `````              @@@@@@r   print_summaryr   =  s   J %%</$$ ..557 		AA
A!BGGOOAaD4E4E$F G! K
 #(QJE		  
!00 (Du}.3O!#'D( '
 !'R2!2	R=A7@A![1_-AI@
!'R6!6	R=A7@A![1_-AIP
&&--/ 	 AaN	  r%+&5e[IK-^ x

|1%&S;j)$S;3<(3 (3T B k!n{1~> ES;u45&u'I'IJ 2..!
 'u'>'>? 253J3J K&u'B'BC 253N3N O-0II
+>>? @ !234A	7 
_- . !678	; 
 !4 5 6 !:;<A	? S;"5(K@e B Bs   MM
c                    |dv sJ | j                         \  }}t        |j                  d         D ]  }|dk(  r:|\  }}}|||f}	|dd|f   j                  |	      }
t	        j
                  |
d      }
n9|\  }}}|||f}	|dd|f   j                  |	      }
t	        j
                  |
d      }
t	        j                  |
t	        j                  |      f      |dd|f<    | j                  ||g       y)a]  Utility useful when changing a convnet's `data_format`.

    When porting the weights of a convnet from one data format to the other,
    if the convnet includes a `Flatten` layer
    (applied to the last convolutional feature map)
    followed by a `Dense` layer, the weights of that `Dense` layer
    should be updated to reflect the new dimension ordering.

    Args:
        dense: The target `Dense` layer.
        previous_feature_map_shape: A shape tuple of 3 integers,
            e.g. `(512, 7, 7)`. The shape of the convolutional
            feature map right before the `Flatten` layer that
            came before the target `Dense` layer.
        target_data_format: One of "channels_last", "channels_first".
            Set it "channels_last"
            if converting a "channels_first" model to "channels_last",
            or reciprocally.
    >   channels_lastchannels_firstr|   r   N)r   r   r|   )r|   r   r   )get_weightsr   r3   reshaper5   	transposer6   set_weights)denseprevious_feature_map_shapetarget_data_formatkernelbiasr   chr>   original_fm_shapekis              r   !convert_dense_weights_data_formatr   `  s   , !DDDD$$&LFD6<<?# N!110GAq!!"Aq	1%%&78Bb),B0GAq!!"Aq	1%%&78Bb),Bzz"rww/I'J&LMq!tN 
vtn%r"   c                 ^    t        | dd       sy| j                  dk7  xr | j                  dk7  S )N_keras_api_namesF)zkeras.layers.Layer)rc   r   _keras_api_names_v1)r   s    r   is_builtin_layerr     s@    5,d3 !! &  ?

#
#'>
>?r"   c                 |     t        j                         t        j                          fd       }|_        |S )a
  Lightweight decorator for caching lazily constructed properties.

    When to use:
    This decorator provides simple caching with minimal overhead. It is designed
    for properties which are expensive to compute and static over the life of a
    class instance, and provides no mechanism for cache invalidation. Thus it is
    best suited for lazily exposing derived properties of other static data.

    For classes with custom getattr / setattr behavior (such as trackable
    objects), storing cache results as object attributes is not performant.
    Instead, a specialized cache can significantly reduce property lookup
    overhead. (While still allowing the decorated property to be lazily
    computed.) Consider the following class:

    ```
    class MyClass:
      def __setattr__(self, key, value):
        # Some expensive class specific code
        # ...
        # ...

        super(MyClass, self).__setattr__(key, value)

      @property
      def thing(self):
        # `thing` is expensive to compute (and may not even be requested), so we
        # want to lazily compute it and then cache it.
        output = getattr(self, '_thing', None)
        if output is None:
          self._thing = output = compute_thing(self)
        return output
    ```

    It's also worth noting that ANY overriding of __setattr__, even something as
    simple as:
    ```
      def __setattr__(self, key, value):
        super(MyClass, self).__setattr__(key, value)
    ```

    Slows down attribute assignment by nearly 10x.

    By contrast, replacing the definition of `thing` with the following
    sidesteps the expensive __setattr__ altogether:

    '''
    @property
    @tracking.cached_per_instance
    def thing(self):
      # `thing` is expensive to compute (and may not even be requested), so we
      # want to lazily compute it and then cache it.
      return compute_thing(self)
    '''

    Performance:
    The overhead for this decorator is ~0.4 us / call. A much lower overhead
    implementation (~0.085 us / call) can be achieved by using a custom dict
    type:

    ```
    def dict_based_cache(f):
      class Cache(dict):
        __slots__ = ()
        def __missing__(self, key):
          self[key] = output = f(key)
          return output

      return property(Cache().__getitem__)
    ```

    However, that implementation holds class instances as keys, and as a result
    blocks garbage collection. (And modifying it to use weakref's as keys raises
    the lookup overhead to ~0.4 us) As a result, the WeakKeyDictionary
    implementation below turns out to be more prudent.

    Args:
      f: The function to cache.

    Returns:
      f decorated with simple caching behavior.
    c                 H    j                  |       }| |       x| <   }|S r	   )rW   )itemoutputcachefs     r   wrappedz$cached_per_instance.<locals>.wrapped  s,    4>#$T7*E$K&r"   )weakrefWeakKeyDictionary	functoolswrapsr   )r   r   r   s   ` @r   cached_per_instancer    s=    f %%'E__Q  GMNr"   c              #   >  K   t               }| ddd   }|r|j                         }t        |      |v r |j                  t        |             t	        |d      rt        |t              s| n(t        |dd      xs g }|j                  |ddd          |ryyw)z4Filter out empty Layer-like containers and uniquify.Nr}   	_is_layerr   )	rR   popr8   addr   r&   typerc   extend)
layer_listexistingto_visitobj
sub_layerss        r   filter_empty_layer_containersr    s      uH$B$H
llnc7hRW3$ZT-BI h5;J OOJtt,- s   BBBc                      e Zd ZdZd Zed        Zed        Zej                  d        Zee	d               Z
ed        Zej                  d        Zed	        Zej                  d
        Zed        ZddZddZ	 	 ddZd Zy)CallFunctionSpeczKCaches the spec and provides utilities for handling call function
    args.c                    || _         t        | j                   j                        | _        | j                  r&| j                  d   dk(  r| j                  dd | _        | xj                  | j                   j                  xs g z  c_        | j                   j
                  du}d| j                  v xs || _        d| j                  v xs || _        | j                   j                  xs g }t               }t        dt        |      z  d      D ]  }||   || j                  |   <    |j                  | j                   j                  xs i        |j                  d      | _        y)zInitialies a `CallFunctionSpec`.

        Args:
          full_argspec: the FullArgSpec of a call function of a layer.
        r   selfr|   Ntrainingmaskr}   )_full_argspecrP   args
_arg_names
kwonlyargsvarkw_expects_training_arg_expects_mask_argdefaultsdictr   rf   updatekwonlydefaultsrW   _default_training_arg)r  full_argspeccall_accepts_kwargscall_fn_defaultsr  r   s         r   __init__zCallFunctionSpec.__init__
  sD    *t11667??tq1V;"ooab1DO4--88>B>"0066dB$//)@-@ 	" doo%<)< 	  --66<"6 rC 01115 	?A+;A+>HT__Q'(	? 	**99?R@%-\\*%="r"   c                     | j                   S )z-Returns the FullArgSpec of the call function.)r  r  s    r   r!  zCallFunctionSpec.full_argspec+  s     !!!r"   c                     | j                   S )z%List of names of args and kwonlyargs.r  r&  s    r   	arg_nameszCallFunctionSpec.arg_names0  s     r"   c                     || _         y r	   r(  r  values     r   r)  zCallFunctionSpec.arg_names6  s	    r"   c                 ^    t               }t        | j                        D ]
  \  }}|||<    |S )z:Returns a dict mapping arg names to their index positions.)r  r   r  )r  call_fn_arg_positionsposargs       r   arg_positionszCallFunctionSpec.arg_positions:  s9     !%!$//2 	-HC),!#&	-$$r"   c                     | j                   S )z9Whether the call function uses 'training' as a parameter.r  r&  s    r   expects_training_argz%CallFunctionSpec.expects_training_argE       )))r"   c                     || _         y r	   r3  r+  s     r   r4  z%CallFunctionSpec.expects_training_argJ  s
    %*"r"   c                     | j                   S )z5Whether the call function uses `mask` as a parameter.r  r&  s    r   expects_mask_argz!CallFunctionSpec.expects_mask_argN  s     %%%r"   c                     || _         y r	   r8  r+  s     r   r9  z!CallFunctionSpec.expects_mask_argS  s
    !&r"   c                     | j                   S )z3The default value given to the "training" argument.)r   r&  s    r   default_training_argz%CallFunctionSpec.default_training_argW  r5  r"   c                 j    |s|sy||v ry| j                   }|s|dd }|t        t        ||            v S )a  Returns true if argument is present in `args` or `kwargs`.

        Args:
          arg_name: String name of the argument to find.
          args: Tuple of args passed to the call function.
          kwargs: Dictionary of kwargs  passed to the call function.
          inputs_in_args: Whether the input argument (the first argument in the
            call function) is included in `args`. Defaults to `False`.

        Returns:
          True if argument with `arg_name` is present in `args` or `kwargs`.
        FTr|   Nr  r  zip)r  r,   r  kwargsinputs_in_argscall_fn_argss         r   arg_was_passedzCallFunctionSpec.arg_was_passed\  sF     Fv'+L4L$ 7888r"   c                 n    ||v r||   S | j                   }|s|dd }t        t        ||            }||   S )ak  Retrieves the value for the argument with name `arg_name`.

        Args:
          arg_name: String name of the argument to find.
          args: Tuple of args passed to the call function.
          kwargs: Dictionary of kwargs  passed to the call function.
          inputs_in_args: Whether the input argument (the first argument in the
            call function) is included in `args`. Defaults to `False`.

        Returns:
          The value of the argument with name `arg_name`, extracted from `args`
          or `kwargs`.

        Raises:
          KeyError if the value of `arg_name` cannot be found.
        r|   Nr>  )r  r,   r  r@  rA  rB  	args_dicts          r   get_arg_valuezCallFunctionSpec.get_arg_valueu  sK    " v(##'+L\401	""r"   c                    | j                   j                  rH	 | j                   j                  j                  |      }| j                   j                  d   dk(  r|dz  }n| j
                  j                  |d      }|2|s|dz
  }t        |      |kD  rt        |      }|||<   t        |      |fS ||r|j                  |d       ||fS |||<   ||fS # t        $ r d}Y dw xY w)a  Sets the value of an argument into the given args/kwargs.

        Args:
          arg_name: String name of the argument to find.
          new_value: New value to give to the argument.
          args: Tuple of args passed to the call function.
          kwargs: Dictionary of kwargs  passed to the call function.
          inputs_in_args: Whether the input argument (the first argument in the
            call function) is included in `args`. Defaults to `False`.
          pop_kwarg_if_none: If the new value is `None`, and this is `True`,
            then the argument is deleted from `kwargs`.

        Returns:
          The updated `(args, kwargs)`.
        r   r  r|   N)r!  varargsr  indexr(   r1  rW   rf   rP   rV   r  )r  r,   	new_valuer  r@  rA  pop_kwarg_if_nonearg_poss           r   set_arg_valuezCallFunctionSpec.set_arg_value  s    0 $$++0066x@$$))!,6qLG ((,,Xt<G!!A+4y7"Dz )WT{F**!2JJx& V|  )F8V|#  s   AC C C c                     |r|d   }|dd }nP| j                   d   |v r4t        j                  |      }|j                  | j                   d         }nt        d      |||fS )z2Splits (args, kwargs) into (inputs, args, kwargs).r   r|   Nz9The first argument to `Layer.call` must always be passed.)r  copyr  r(   )r  r  r@  inputss       r   split_out_first_argz$CallFunctionSpec.split_out_first_arg  sp    
 !WF8D__Q6)YYv&FZZ 23FK  tV##r"   N)FFF)r   
__module____qualname____doc__r$  propertyr!  r)  setterr  r1  r4  r9  r<  rC  rF  rM  rQ  r
   r"   r   r  r    s    >B " "  
     %  % * *   + !+ & & ' ' * *92#@ .`$r"   r  z&keras.utils.warmstart_embedding_matrixc           
         t        |       } t        |      }t        j                  |      } |t        |      |j                  d   f|j
                        }t        t        | t        t        |                         }g }g }t        |      D ]8  \  }}	|	|v s|j                  ||	          |j                  t        |             : |rBt        j                  ||      }
t        j                  |t        j                  |d      |
      }|S )ah  Warm start embedding matrix with changing vocab.

    This util can be used to warmstart the embedding layer matrix when
    vocabulary changes between previously saved checkpoint and model.
    Vocabulary change could mean, the size of the new vocab is different or the
    vocabulary is reshuffled or new vocabulary has been added to old vocabulary.
    If the vocabulary size changes, size of the embedding layer matrix also
    changes. This util remaps the old vocabulary embeddings to the new embedding
    layer matrix.

    Example:
    Here is an example that demonstrates how to use the
    `warmstart_embedding_matrix` util.
    >>> import tf_keras.src as keras
    >>> vocab_base = tf.convert_to_tensor(["unk", "a", "b", "c"])
    >>> vocab_new = tf.convert_to_tensor(
    ...        ["unk", "unk", "a", "b", "c", "d", "e"])
    >>> vectorized_vocab_base = np.random.rand(vocab_base.shape[0], 3)
    >>> vectorized_vocab_new = np.random.rand(vocab_new.shape[0], 3)
    >>> warmstarted_embedding_matrix = warmstart_embedding_matrix(
    ...       base_vocabulary=vocab_base,
    ...       new_vocabulary=vocab_new,
    ...       base_embeddings=vectorized_vocab_base,
    ...       new_embeddings_initializer=keras.initializers.Constant(
    ...         vectorized_vocab_new))

    Here is an example that demonstrates how to get vocabulary and embedding
    weights from layers, use the `warmstart_embedding_matrix` util to remap the
    layer embeddings and continue with model training.
    ```
    # get old and new vocabulary by using layer.get_vocabulary()
    # for example assume TextVectorization layer is used
    base_vocabulary = old_text_vectorization_layer.get_vocabulary()
    new_vocabulary = new_text_vectorization_layer.get_vocabulary()
    # get previous embedding layer weights
    embedding_weights_base = model.get_layer('embedding').get_weights()[0]
    warmstarted_embedding = keras.utils.warmstart_embedding_matrix(
                                  base_vocabulary,
                                  new_vocabulary,
                                  base_embeddings=embedding_weights_base,
                                  new_embeddings_initializer="uniform")
    updated_embedding_variable = tf.Variable(warmstarted_embedding)

    # update embedding layer weights
    model.layers[1].embeddings = updated_embedding_variable
    model.fit(..)
    # continue with model training

    ```

    Args:
        base_vocabulary: The list of vocabulary terms that
          the preexisting embedding matrix `base_embeddings` represents.
          It can be either a 1D array/tensor or a tuple/list of vocabulary
          terms (strings), or a path to a vocabulary text file. If passing a
           file path, the file should contain one line per term in the
           vocabulary.
        new_vocabulary: The list of vocabulary terms for the new vocabulary
           (same format as above).
        base_embeddings: NumPy array or tensor representing the preexisting
          embedding matrix.
        new_embeddings_initializer: Initializer for embedding vectors for
          previously unseen terms to be added to the new embedding matrix (see
          `keras.initializers`). new_embedding matrix
          needs to be specified with "constant" initializer.
          matrix. None means "uniform". Default value is None.

    Returns:
      tf.tensor of remapped embedding layer matrix

    r|   )r3   rE   )axis)convert_vocab_to_listr   rW   rf   r3   rE   r  r?  r   r   r   r;   r   gathertensor_scatter_nd_updateexpand_dims)base_vocabularynew_vocabularybase_embeddingsnew_embeddings_initializernew_embeddingbase_vocabulary_dictindices_base_vocabularyindices_new_vocabularyrI  keyvalues_to_updates              r   warmstart_embedding_matrixrh    s   ^ ,O<O*>:N ".!1!12L!M.>"O$9$9!$<=##M  OU3#789 !/ 6
s&&#**+?+DE"))#e*56 99_6MN33NN1:

 r"   c                 x   g }t        j                  |       rt        | j                               }nt	        | t
        j                  t        t        f      rt        |       }nt	        | t              rt         j                  j                  j                  |       st        d|  d      t         j                  j                  j                  | d      5 }|j                         j                         }ddd       nt        dt!        |        d      t#        |      dk(  rt        d      |S # 1 sw Y   $xY w)	z!Convert input vacabulary to list.zVocabulary file z does not exist.rNzkVocabulary is expected to be either a NumPy array, list, 1D tensor or a vocabulary text file. Instead type z was received.r   zVocabulary is expected to be either a NumPy array, list, 1D tensor or a vocabulary text file with at least one token. Received 0 instead.)r   	is_tensorrP   numpyr&   r5   ndarrayrV   r'   iogfileexistsr(   GFileread
splitlinesr  rf   )vocab
vocab_listvocabulary_files      r   rZ  rZ  A  s   J	||E%++-(
	EBJJt4	5%[
	E3	uu{{!!%(/w6FGHHUU[[uc* 	=o(--/::<J	= 	= GE{m>+
 	

 :!#
 	

 	= 	=s   D00D9)NNrR  r	   )NNNFFN)r   )uniform)!rU  rO  r   r   r   rl  r5   tensorflow.compat.v2compatv2r   tf_keras.srcr   tf_keras.src.utilsr    tensorflow.python.util.tf_exportr   r   r1   rC   rJ   r^   rt   rg   r   r   r   r   r  r  r  rh  rZ  r
   r"   r   <module>r~     s     6   	   ! ! % ' : -.#" /#"V !
HD&0/Jd/$d	=34p `AH	 ;K$&N?]@.(H$ H$V 67
  )	l 8l^r"   