
    BVhYb                        d 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 ddlmZ ddlmZ dZ G d de      Zej-                  ej.                          G d de      Z G d de      Zej5                  ej6                  d       ej5                  ej6                  d       ej5                  ej6                  d       ej5                  ej6                  d       ej5                  ej6                  d        G d de	j8                        Z G d de      Z G d de      Zej.                  efej@                  efej6                  efeefgZ!d Z"d  Z#d! Z$d$d#Z%y")%z9Keras Input Tensor used to track functional API Topology.    )constant_op)dtypes)sparse_tensor)tensor)tensor_shape)	type_spec)object_identity)	array_ops)ragged_operators)ragged_tensor)nest   c                      e Zd ZdZddZed        Zed        Zed        Z	edd       Z
d Zd	ej                  fd
Zd Zed        Zd ZdZd Zed        Zd Zd Zd Zed        Zd Zd Zed        Zed        Zed        Zy)KerasTensora  A representation of a Keras in/output during Functional API construction.

  `KerasTensor`s are tensor-like objects that represent the symbolic inputs
  and outputs of Keras layers during Functional model construction. They are
  comprised of the `tf.TypeSpec` of the (Composite)Tensor that will be
  consumed/produced in the corresponding location of the Functional model.

  KerasTensors are intended as a private API, so users should never need to
  directly instantiate `KerasTensor`s.

  **Building Functional Models with KerasTensors**
  `tf.keras.Input` produces `KerasTensor`s that represent the symbolic inputs
  to your model.

  Passing a `KerasTensor` to a `tf.keras.Layer` `__call__` lets the layer know
  that you are building a Functional model. The layer __call__ will
  infer the output signature and return `KerasTensor`s with `tf.TypeSpec`s
  corresponding to the symbolic outputs of that layer call. These output
  `KerasTensor`s will have all of the internal KerasHistory metadata attached
  to them that Keras needs to construct a Functional Model.

  Currently, layers infer the output signature by:
    * creating a scratch `FuncGraph`
    * making placeholders in the scratch graph that match the input typespecs
    * Calling `layer.call` on these placeholders
    * extracting the signatures of the outputs before clearing the scratch graph

  (Note: names assigned to KerasTensors by this process are not guaranteed to
  be unique, and are subject to implementation details).

  `tf.nest` methods are used to insure all of the inputs/output data
  structures get maintained, with elements swapped between KerasTensors and
  placeholders.

  In rare cases (such as when directly manipulating shapes using Keras layers),
  the layer may be able to partially infer the value of the output in addition
  to just inferring the signature.
  When this happens, the returned KerasTensor will also contain the inferred
  value information. Follow-on layers can use this information.
  during their own output signature inference.
  E.g. if one layer produces a symbolic `KerasTensor` that the next layer uses
  as the shape of its outputs, partially knowing the value helps infer the
  output shape.

  **Automatically converting TF APIs to layers**:
  If you passing a `KerasTensor` to a TF API that supports dispatching,
  Keras will automatically turn that API call into a lambda
  layer in the Functional model, and return KerasTensors representing the
  symbolic outputs.

  Most TF APIs that take only tensors as input and produce output tensors
  will support dispatching.

  Calling a `tf.function` does not support dispatching, so you cannot pass
  `KerasTensor`s as inputs to a `tf.function`.

  Higher-order APIs that take methods which produce tensors (e.g. `tf.while`,
  `tf.map_fn`, `tf.cond`) also do not currently support dispatching. So, you
  cannot directly pass KerasTensors as inputs to these APIs either. If you
  want to use these APIs inside of a Functional model, you must put them inside
  of a custom layer.

  Args:
    type_spec: The `tf.TypeSpec` for the symbolic input created by
      `tf.keras.Input`, or symbolically inferred for the output
      during a symbolic layer `__call__`.
    inferred_value: (Optional) a non-symbolic static value, possibly partially
      specified, that could be symbolically inferred for the outputs during
      a symbolic layer `__call__`. This will generally only happen when
      grabbing and manipulating `tf.int32` shapes directly as tensors.
      Statically inferring values in this way and storing them in the
      KerasTensor allows follow-on layers to infer output signatures
      more effectively. (e.g. when using a symbolic shape tensor to later
      construct a tensor with that shape).
    name: (optional) string name for this KerasTensor. Names automatically
      generated by symbolic layer `__call__`s are not guaranteed to be unique,
      and are subject to implementation details.
  Nc                 x    t        |t        j                        st        d      || _        || _        || _        y)zConstructs a KerasTensor.z6KerasTensors must be constructed with a `tf.TypeSpec`.N)
isinstancetype_spec_moduleTypeSpec
ValueError
_type_spec_inferred_value_name)selfr   inferred_valuenames       [/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/keras/engine/keras_tensor.py__init__zKerasTensor.__init__w   s5    i!1!:!:;OPPDO)DDJ    c                     | j                   S )zFReturns the `tf.TypeSpec` symbolically inferred for this Keras output.)r   r   s    r   r   zKerasTensor.type_spec   s     ??r   c                 .    | j                   j                  S )zFReturns the `TensorShape` symbolically inferred for this Keras output.)r   _shaper    s    r   shapezKerasTensor.shape        ??!!!r   c                 0   t        |t        j                        rt        |dd      }t	        j
                  |      }d}|j                  t        j                  k(  r|j                  j                  l|j                  j                  dk  rSt        j                  |      j                  }|j                  r%|j                         }t        |      t         kD  rd}nd}t#        |||      S t        |dd      }t	        j
                  |      } | ||      S )CConvert a traced (composite)tensor to a representative KerasTensor.r   N   r#   )r   r   r   )r   
tensor_libTensorgetattrr   type_spec_from_valuedtyper   int32r#   rankr
   onesdimsas_listlen_MAX_TENSOR_RANKr   )clsr   r   r   r   s        r   from_tensorzKerasTensor.from_tensor   s     &*++,VVT*d"77?in
//V\\
)ioo.B.B.Noo""Q&& #f5;;)113. #33!N.>MM VVT*d"77?i&&r   c                      | ||      S )N)r   r    r6   r   r   s      r   from_type_speczKerasTensor.from_type_spec   s    ..r   c                 <   | j                   lt        j                  t        j                  | j                   t        j
                              }| j                  j                  j                  dk(  r|d   }|S d }t        j                  || j                  d      S )z5Convert this KerasTensor to a placeholder in a graph.)r#   r.   r   c                 V    t        j                  | j                  | j                        S N)r
   placeholderr.   r#   )	components    r   component_to_placeholderz=KerasTensor._to_placeholder.<locals>.component_to_placeholder   s    ""9??IOODDr   T)expand_composites)
r   r
   r#   r?   r   r/   r   r0   r   map_structure)r   r   rA   s      r   _to_placeholderzKerasTensor._to_placeholder   s     ' !


((>?n 
			"	"a	' (*E  $..DJ Jr   returnc                     | j                   S r>   r(   r    s    r   	get_shapezKerasTensor.get_shape   s    ::r   c                     t        d      )Na_  Keras symbolic inputs/outputs do not implement `__len__`. You may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model. This error will also get raised if you try asserting a symbolic input/output directly.	TypeErrorr    s    r   __len__zKerasTensor.__len__   s    
 M N Nr   c                     t        d      )Na  Keras symbolic inputs/outputs do not implement `op`. You may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.rI   r    s    r   opzKerasTensor.op   s    
 / 0 0r   c                     t        d| z        )NzATensors are unhashable. (%s)Instead, use tensor.ref() as the key.rI   r    s    r   __hash__zKerasTensor.__hash__   s    
 <>BC D Dr   d   c                     t        d      )Na~  Cannot convert a symbolic Keras input/output to a numpy array. This error may indicate that you're trying to pass a symbolic value to a NumPy call, which is not supported. Or, you may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model.rI   r    s    r   	__array__zKerasTensor.__array__   s    
	#$ $r   c                      y)NTr9   r    s    r   is_tensor_likezKerasTensor.is_tensor_like  s    r   c                 &   t        |t        j                        st        j                  |      }|j                  |j                  D cg c]  }|j                   }}t        t        |            D ];  }||   	| j                  j                   | j                  j                  |   ||<   = t        j                  |      }| j                  j                  |      st        d| j                  d|      || j                  _        yc c}w )zFUpdates the shape of this KerasTensor. Mimics `tf.Tensor.set_shape()`.Nz$Keras symbolic input/output's shape z& is notcompatible with supplied shape )r   r   TensorShaper2   valueranger4   r#   is_compatible_withr   r   r"   )r   r#   dimdim_lists       r   	set_shapezKerasTensor.set_shape  s    e\556&&u-ezz',zz2#))2h2s8}% /#C= TZZ__%@**//#.(3-/ &&x0e::((/ ::u 
  %doo 3s   
Dc                 
   d}d}d}t        | d      r&| j                  j                  }d|j                  d}| j                  d| j                  z  }| j                  d| j
                  z  }d| j                  |||dS )	N _keras_historyz!, description="created by layer 'z'"z, inferred_value=%sz, name='%s'zKerasTensor(type_spec=))hasattrr_   layerr   r   r   r   )r   symbolic_descriptioninferred_value_stringname_stringrb   s        r   __str__zKerasTensor.__str__  s    Kt%&!!''e7<zz
C '
$"6"6
6 yy#djj0k-)+ +r   c                 l   d}d}t        | j                  t        j                        r'd| j                  d| j
                  j                  }nd| j                  z  }t        | d      r&| j                  j                  }d|j                  d}| j                  d| j                  z  }d	|||d
S )Nr^   zshape=z dtype=ztype_spec=%sr_   z (created by layer 'z')z inferred_value=%sz<KerasTensor: >)r   r   r*   
TensorSpecr#   r.   r   ra   r_   rb   r   )r   rc   rd   type_spec_stringrb   s        r   __repr__zKerasTensor.__repr__/  s    $..*"7"7804

DJJOOL'$..8t%&!!''e=BZZI'
!5!5
5  	/1EG Gr   c                 .    | j                   j                  S )z@Returns the `dtype` symbolically inferred for this Keras output.)r   _dtyper    s    r   r.   zKerasTensor.dtype@  r$   r   c                 ,    t        j                  |       S )a  Returns a hashable reference object to this KerasTensor.

    The primary use case for this API is to put KerasTensors in a
    set/dictionary. We can't put tensors in a set/dictionary as
    `tensor.__hash__()` is not available and tensor equality (`==`) is supposed
    to produce a tensor representing if the two inputs are equal.

    See the documentation of `tf.Tensor.ref()` for more info.
    )r	   	Referencer    s    r   refzKerasTensor.refI  s     $$T**r   c                    d }| j                   j                  -| j                   j                  D cg c]  }|j                   }}|t	        d      |st	        d      |d   t	        d      t        | |d         S c c}w )Nz0Cannot iterate over a Tensor with unknown shape.zCannot iterate over a scalar.r   z:Cannot iterate over a Tensor with unknown first dimension.)r#   ndimsr2   rW   rJ   _KerasTensorIterator)r   r#   rZ   s      r   __iter__zKerasTensor.__iter__U  s    Ezz#$(JJOO4Ssyy4e4}HII566Qx
FH HeAh// 5s   A?c                     | j                   S )zEReturns the (non-unique, optional) name of this symbolic Keras value.)r   r    s    r   r   zKerasTensor.namec  s     ::r   c                     t         j                  j                  D ]  }| j                  ||        t	        |d      r| j                  |d       yy)z%Register overloads for all operators.experimental_refN)r*   r+   OVERLOADABLE_OPERATORS_overload_operatorra   )r6   tensor_classoperators      r   _overload_all_operatorsz#KerasTensor._overload_all_operatorsh  sR     %%<< 5	\845
 |/0	\+=> 1r   c                 P    t        ||      }t        |d|      }t        | ||       y)a  Overload an operator with the same implementation as a base Tensor class.

    We pull the operator out of the class dynamically to avoid ordering issues.

    Args:
      tensor_class: The (Composite)Tensor to get the method from.
      operator: string. The operator name.
    __func__N)r,   setattr)r6   rz   r{   tensor_opers       r   ry   zKerasTensor._overload_operators  s,     ,1K
 +z;?KC;'r   )NNr>   )__name__
__module____qualname____doc__r   propertyr   r#   classmethodr7   r;   rD   r   rV   rG   rK   rM   rO   __array_priority__rR   rT   r\   rf   rk   r.   rp   rt   r   r|   ry   r9   r   r   r   r   '   s"   M^   " " '' ''R / /J811 N 0 0D 	$  %$+$G" " "
+0   ? ? ( (r   r   c                       e Zd ZdZd Zy)SparseKerasTensorzA specialized KerasTensor representation for `tf.sparse.SparseTensor`s.

  Specifically, it specializes the conversion to a placeholder in order
  to maintain dense shape information.
  c                 p    | j                   }t        j                  |j                  |j                        S )N)r.   r#   )r   r
   sparse_placeholderr.   r#   )r   specs     r   rD   z!SparseKerasTensor._to_placeholder  s(    >>D ''djj

KKr   N)r   r   r   r   rD   r9   r   r   r   r     s    Lr   r   c                   2     e Zd ZdZ fdZed        Z xZS )RaggedKerasTensora  A specialized KerasTensor representation for `tf.RaggedTensor`s.

  Specifically, it:

  1. Specializes the conversion to a placeholder in order
  to maintain shape information for non-ragged dimensions.
  2. Overloads the KerasTensor's operators with the RaggedTensor versions
  when they don't match the `tf.Tensor` versions
  3. Exposes some of the instance method/attribute that are unique to
  the RaggedTensor API (such as ragged_rank).
  c                    | j                   }|j                  dk(  s|j                  j                  t        t
        |          S |j                  |j                  d  }t        j                  |j                  |      }g }d}|j                  D ],  }||t        |dd      d }n||z  }|j                  |       . t        |j                  dd      D ]  }|j                  |   }|t        |dd      S||dz
     }||dz   }t        j                  |j                  |g      }	t        j                  j!                  ||	d      }tt#        j$                  ||j                        }
t        j                  j'                  ||
d      } |S )Nr      rW   TF)validate)r   ragged_rankr#   r0   superr   rD   r
   r?   r.   r,   appendrX   row_splits_dtyper   RaggedTensorfrom_row_splitsr   constantfrom_uniform_row_length)r   ragged_spec
flat_shaperesultknown_num_splitsprod	axis_sizeaxis
num_splitssplitsrowlen	__class__s              r   rD   z!RaggedKerasTensor._to_placeholder  s   ..K!#{'8'8'='='E$d;=="";#:#:#;<J"";#4#4jAFD && $			Iw-5$	!$d#$ k--q"5 ,##D)i		wy'4@H%d1f-
!!A~*&&((:,8++;;FU < , %%i1M1MN++CCFU D ,, Mr   c                 .    | j                   j                  S r>   )r   r   r    s    r   r   zRaggedKerasTensor.ragged_rank  s    >>%%%r   )r   r   r   r   rD   r   r   __classcell__r   s   @r   r   r     s"    
!F & &r   r   __getitem____add____radd____mul____rmul__c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	UserRegisteredSpecz7TypeSpec to represent user-registered symbolic objects.c                 .    || _         || _        || _        y r>   )r#   rm   r.   )r   r#   r.   s      r   r   zUserRegisteredSpec.__init__  s    DJDKDJr   c                     t         r>   NotImplementedErrorr    s    r   _component_specsz#UserRegisteredSpec._component_specs      
r   c                     t         r>   r   )r   
componentss     r   _from_componentsz#UserRegisteredSpec._from_components  r   r   c                     t         r>   r   r    s    r   
_serializezUserRegisteredSpec._serialize  r   r   c                     t         r>   r   )r   rW   s     r   _to_componentsz!UserRegisteredSpec._to_components  r   r   c                     t         r>   r   r    s    r   
value_typezUserRegisteredSpec.value_type  r   r   N)
r   r   r   r   r   r   r   r   r   r   r9   r   r   r   r     s#    ?
r   r   c                   J     e Zd ZdZ fdZed        Zedd       Zd Z xZ	S )UserRegisteredTypeKerasTensorzAKerasTensor that represents legacy register_symbolic_tensor_type.c                     |}|| _         t        |j                  |j                        }t	        |dd       }t
        t        |   ||       y )Nr   ) _user_registered_symbolic_objectr   r#   r.   r,   r   r   r   )r   user_registered_symbolic_objectxr   r   r   s        r   r   z&UserRegisteredTypeKerasTensor.__init__  sD    'A,-D)"177AGG4I1fd#D	
'7	4Hr   c                      | |      S r>   r9   )r6   r   s     r   r7   z)UserRegisteredTypeKerasTensor.from_tensor	  s    v;r   c                     t        d|z        )Nz?You cannot instantiate a KerasTensor directly from TypeSpec: %sr   r:   s      r   r;   z,UserRegisteredTypeKerasTensor.from_type_spec  s    
 ;=FG H Hr   c                     | j                   S r>   )r   r    s    r   rD   z-UserRegisteredTypeKerasTensor._to_placeholder  s    000r   r>   )
r   r   r   r   r   r   r7   r;   rD   r   r   s   @r   r   r     s;    II   H H1r   r   c                   "    e Zd ZdZd Zd Zd Zy)rs   zHIterates over the leading dim of a KerasTensor. Performs 0 error checks.c                 .    || _         d| _        || _        y )Nr   )_tensor_index_limit)r   r   dim0s      r   r   z_KerasTensorIterator.__init__  s    DLDKDKr   c                     | S r>   r9   r    s    r   rt   z_KerasTensorIterator.__iter__  s    Kr   c                     | j                   | j                  k(  rt        | j                  | j                      }| xj                   dz  c_         |S )Nr   )r   r   StopIterationr   )r   r   s     r   __next__z_KerasTensorIterator.__next__!  s=    {{dkk!\\$++&FKK1KMr   N)r   r   r   r   r   rt   r   r9   r   r   rs   rs     s    P
r   rs   c                 4    t         j                  d| |f       y)z>Register a specialized KerasTensor subclass for a Tensor type.r   N)keras_tensor_classesinsert)r6   keras_tensor_subclasss     r   $register_keras_tensor_specializationr   9  s     b3(=">?r   c                 F    t        | t              r| j                         S | S )zFConstruct a graph placeholder to represent a KerasTensor when tracing.)r   r   rD   )r   s    r   keras_tensor_to_placeholderr   ?  s     ;Hr   c                     d}t         D ]  \  }}t        | |      s|} n |j                  |       }t        | d      rt	        | j
                        |_        |S )r&   N_keras_mask)r   r   r7   ra   keras_tensor_from_tensorr   )r   keras_tensor_clstensor_typer6   outs        r   r   r   G  sd     . k3&+&
 	$$V,#V]#.v/A/ABCO	*r   Nc                     d}| j                   }t        D ]  \  }}t        ||      s|} n |j                  | |      S )z3Convert a TypeSpec to a representative KerasTensor.Nr)   )r   r   
issubclassr;   )r   r   r   r   r   r6   s         r   keras_tensor_from_type_specr   X  sT     ##*. k3*k*
 
	(	(	(	>>r   r>   )&r   tensorflow.python.frameworkr   r   r   r   r*   r   r   r   tensorflow.python.keras.utilsr	   tensorflow.python.opsr
   tensorflow.python.ops.raggedr   r   tensorflow.python.utilr   r5   objectr   r|   r+   r   r   ry   r   r   r   r   rs   SparseTensorr   r   r   r   r   r9   r   r   <module>r      sd   @ 3 . 5 < 4 E 9 + 9 6 '  ](& ](@  # #J$5$5 6L L$2& 2&j  $ $]%?%? O  $ $]%?%? K  $ $]%?%? L  $ $]%?%? K  $ $]%?%? L)22 <1K 106 8 $!23!23[	 @"?r   