
    BVhRA                        d Z ddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ 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dlmZ  G d dej>                        Z  ed       G d dejB                  ejD                  ejF                               Z! ejH                  dg d      Z% ed       G d dejL                               Z' ejP                   ejR                  e'ejT                  jV                                edg      d$d       Z,	 	 	 d%dZ-	 	 	 d%d Z.d$d!Z/d"Z0d%d#Z1 ejd                  e!e1       y)&zIndexed slices.    N)
struct_pb2)tf2)context)composite_tensor)composite_tensor_gradient)dtypes)ops)tensor_conversion_registry)tensor_shape)tensor_spec)tensor_util)	type_spec)gen_math_ops)nested_structure_coder)internal)collections_abc)	tf_exportc                       e Zd ZdZd Zd Zy)$IndexedSlicesCompositeTensorGradientz*CompositeTensorGradient for IndexedSlices.c                     |S N selfvalues     Z/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/framework/indexed_slices.pyget_gradient_componentsz<IndexedSlicesCompositeTensorGradient.get_gradient_components.   s    L    c                     |S r   r   )r   r   component_gradss      r   replace_gradient_componentsz@IndexedSlicesCompositeTensorGradient.replace_gradient_components1   s    r   N)__name__
__module____qualname____doc__r   r!   r   r   r   r   r   *   s    2r   r   IndexedSlicesc                      e Zd ZdZddZed        Zed        Zed        Zed        Z	ed        Z
ed	        Zed
ej                  fd       Zed        Zed
ej                   fd       Zd Zd Z e       Zed        Zd Zd Zy)r&   aW  A sparse representation of a set of tensor slices at given indices.

  This class is a simple wrapper for a pair of `Tensor` objects:

  * `values`: A `Tensor` of any dtype with shape `[D0, D1, ..., Dn]`.
  * `indices`: A 1-D integer `Tensor` with shape `[D0]`.

  An `IndexedSlices` is typically used to represent a subset of a larger
  tensor `dense` of shape `[LARGE0, D1, .. , DN]` where `LARGE0 >> D0`.
  The values in `indices` are the indices in the first dimension of
  the slices that have been extracted from the larger tensor.

  The dense tensor `dense` represented by an `IndexedSlices` `slices` has

  ```python
  dense[slices.indices[i], :, :, :, ...] = slices.values[i, :, :, :, ...]
  ```

  The `IndexedSlices` class is used principally in the definition of
  gradients for operations that have sparse gradients
  (e.g. `tf.gather`).

  >>> v = tf.Variable([[0.,1, 2], [2, 3, 4], [4, 5, 6], [6, 7, 8]])
  >>> with tf.GradientTape() as tape:
  ...   r = tf.gather(v, [1,3])
  >>> index_slices = tape.gradient(r,v)
  >>> index_slices
  <...IndexedSlices object ...>
  >>> index_slices.indices.numpy()
  array([1, 3], dtype=int32)
  >>> index_slices.values.numpy()
  array([[1., 1., 1.],
         [1., 1., 1.]], dtype=float32)

  Contrast this representation with
  `tf.sparse.SparseTensor`,
  which uses multi-dimensional indices and scalar values.
  Nc                 .    || _         || _        || _        y)zCreates an `IndexedSlices`.N)_values_indices_dense_shape)r   valuesindicesdense_shapes       r   __init__zIndexedSlices.__init__b   s    DLDM#Dr   c                     | j                   S )z/A `Tensor` containing the values of the slices.)r)   r   s    r   r,   zIndexedSlices.valuesh   s     <<r   c                     | j                   S )z4A 1-D `Tensor` containing the indices of the slices.)r*   r1   s    r   r-   zIndexedSlices.indicesm   s     ==r   c                     | j                   S )zFA 1-D `Tensor` containing the shape of the corresponding dense tensor.)r+   r1   s    r   r.   zIndexedSlices.dense_shaper   s     r   c                     | j                   t        j                  d      S t        j                  | j                         S )zyGets the `tf.TensorShape` representing the shape of the dense tensor.

    Returns:
      A `tf.TensorShape` object.
    N)r+   r   TensorShaper   constant_value_as_shaper1   s    r   shapezIndexedSlices.shapew   s8      %%d++..t/@/@AAr   c                 .    | j                   j                  S )z!The name of this `IndexedSlices`.)r,   namer1   s    r   r9   zIndexedSlices.name   s     ;;r   c                 .    | j                   j                  S )zEThe name of the device on which `values` will be produced, or `None`.)r,   devicer1   s    r   r;   zIndexedSlices.device   s     ;;r   returnc                 .    | j                   j                  S )z4The `Operation` that produces `values` as an output.)r,   opr1   s    r   r>   zIndexedSlices.op   s     ;;>>r   c                 .    | j                   j                  S )z'The `DType` of elements in this tensor.)r,   dtyper1   s    r   r@   zIndexedSlices.dtype   s     ;;r   c                 .    | j                   j                  S )zAThe `Graph` that contains the values, indices, and shape tensors.)r)   graphr1   s    r   rB   zIndexedSlices.graph   s     <<r   c                 |    d| j                   d| j                  | j                  d| j                  dS ddS )NzIndexedSlices(indices=z	, values=z, dense_shape= ))r*   r)   r+   r1   s    r   __str__zIndexedSlices.__str__   sS    t||"&"3"3"?$


 	HI I FH	HI Ir   c                 Z    t        | j                   | j                  | j                        S r   )r&   r,   r-   r.   r1   s    r   __neg__zIndexedSlices.__neg__   s!    $++t||T5E5EFFr   c                    | j                   j                  j                  | j                  j                  d d       }t	        j
                  d g      j                  | j                  j                  dd        }| j                  E| j                  j                  }|j                  t        j                  | j                              }nd }t        || j                  | j                   j                  ||      S N   )r*   r7   
merge_withr)   r   r5   concatenater+   r@   r   r6   IndexedSlicesSpec)r   indices_shaper.   dense_shape_dtypes       r   
_type_speczIndexedSlices._type_spec   s    MM''224<<3E3Ebq3IJM**D62>>12 K$++11**

-
-d.?.?
@Bk [$**dmm6I6I.? ?r   c                     |d d }t        j                  d g      j                  |dd        }| j                  d }n| j                  j                  }t        || j                  | j                  j                  ||      S rJ   )r   r5   rM   r+   r@   rN   r*   )r   r7   rO   r.   rP   s        r   _shape_invariant_to_type_specz+IndexedSlices._shape_invariant_to_type_spec   s|    
 "1IM**D62>>uQRyIK ++11[$**dmm6I6I.? ?r   c                 "    | j                         S r   )
_consumersr1   s    r   	consumerszIndexedSlices.consumers   s    ??r   r   )r"   r#   r$   r%   r/   propertyr,   r-   r.   r7   r9   r;   r	   	Operationr>   r@   GraphrB   rF   rH   r   __composite_gradient__rQ   rS   rV   r   r   r   r&   r&   6   s   
%N$       	B 	B     #--     SYY  IG @A? ??r   IndexedSlicesValue)r,   r-   r.   rN   c                       e Zd ZdZg dZ ed       Zdej                  ej                  ddfdZ
d Zed        Zd Zd	 Zy)
rN   z,Type specification for a `tf.IndexedSlices`._shape_values_dtype_indices_dtype_dense_shape_dtype_indices_shapec                     t         S r   )r&   r1   s    r   <lambda>zIndexedSlicesSpec.<lambda>   s    ] r   Nc                 :   t        j                  |      | _        t        j                  |      | _        t        j                  |      | _        |d| _        nt        j                  |      | _        t        j                  |      j                  d      | _	        y)a  Constructs a type specification for a `tf.IndexedSlices`.

    Args:
      shape: The dense shape of the `IndexedSlices`, or `None` to allow any
        dense shape.
      dtype: `tf.DType` of values in the `IndexedSlices`.
      indices_dtype: `tf.DType` of the `indices` in the `IndexedSlices`.  One
        of `tf.int32` or `tf.int64`.
      dense_shape_dtype: `tf.DType` of the `dense_shape` in the `IndexedSlices`.
        One of `tf.int32`, `tf.int64`, or `None` (if the `IndexedSlices` has
        no `dense_shape` tensor).
      indices_shape: The shape of the `indices` component, which indicates
        how many slices are in the `IndexedSlices`.
    NrK   )
r   as_shaper^   r   as_dtyper_   r`   ra   	with_rankrb   )r   r7   r@   indices_dtyperP   rO   s         r   r/   zIndexedSlicesSpec.__init__   sv    " ''.DK/D //-8D  $d &0A Bd&//>HHKDr   c                 t    | j                   | j                  | j                  | j                  | j                  fS r   r]   r1   s    r   
_serializezIndexedSlicesSpec._serialize   s4    KK++T-@-@##T%8%8: :r   c                    | j                   j                  | j                  dd        }t        j                  || j
                        t        j                  | j                   | j                        g}| j                  D|j                  t        j                  | j                  j                  g| j                               t        |      S rJ   )rb   rM   r^   r   
TensorSpecr_   r`   ra   appendndimstuple)r   value_shapespecss      r   _component_specsz"IndexedSlicesSpec._component_specs   s    %%11$++ab/BK{D,>,>?t22D4G4GHJE *ll

 
 $++"3"3!4d6M6M
NP<r   c                     |j                   |j                  |j                  fS |j                  |j                  |j                   fS r   )r.   r,   r-   r   s     r   _to_componentsz IndexedSlicesSpec._to_components   s<     llEMM**llEMM5+<+<==r   c                     t        d |D              r=t        j                         s)t        |      dk(  rt	        |d   |d   d       S t	        | S t        | S )Nc              3   P   K   | ]  }t        |t        j                           y wr   )
isinstancenpndarray).0ts     r   	<genexpr>z5IndexedSlicesSpec._from_components.<locals>.<genexpr>  s     ;!Jq"**%;s   $&   r   rK   )allr   enabledlenr[   r&   )r   tensor_lists     r   _from_componentsz"IndexedSlicesSpec._from_components  sS    ;{;;KKM	[	Q	!+a.+a.$GG!;//K((r   )r"   r#   r$   r%   	__slots__rW   
value_typer   float32int64r/   rk   rs   ru   r   r   r   r   rN   rN      sW    47) 23*v~~#\\T!L4:  >)r   #convert_to_tensor_or_indexed_slices)v1c                      t        | ||d      S )a  Converts the given object to a `Tensor` or an `IndexedSlices`.

  If `value` is an `IndexedSlices` or `SparseTensor` it is returned
  unmodified. Otherwise, it is converted to a `Tensor` using
  `convert_to_tensor()`.

  Args:
    value: An `IndexedSlices`, `SparseTensor`, or an object that can be consumed
      by `convert_to_tensor()`.
    dtype: (Optional.) The required `DType` of the returned `Tensor` or
      `IndexedSlices`.
    name: (Optional.) A name to use if a new `Tensor` is created.

  Returns:
    A `Tensor`, `IndexedSlices`, or `SparseTensor` based on `value`.

  Raises:
    ValueError: If `dtype` does not match the element type of `value`.
  Fr   r@   r9   as_ref),internal_convert_to_tensor_or_indexed_slices)r   r@   r9   s      r   r   r     s    * 
6T%
9 9r   c           	         t        | t        j                        r-t        j                         st        j
                  | |||      S t        | t        j                        rx|rtt        j                  |      j                  | j                        sFt        dt        j                  |      j                   d|  d| j                  j                   d      | S t        j
                  | |||      S )a  Converts the given object to a `Tensor` or an `IndexedSlices`.

  If `value` is an `IndexedSlices` or `SparseTensor` it is returned
  unmodified. Otherwise, it is converted to a `Tensor` using
  `convert_to_tensor()`.

  Args:
    value: An `IndexedSlices`, `SparseTensor`, or an object that can be consumed
      by `convert_to_tensor()`.
    dtype: (Optional.) The required `DType` of the returned `Tensor` or
      `IndexedSlices`.
    name: (Optional.) A name to use if a new `Tensor` is created.
    as_ref: True if the caller wants the results as ref tensors.

  Returns:
    A `Tensor`, `IndexedSlices`, or `SparseTensor` based on `value`.

  Raises:
    ValueError: If `dtype` does not match the element type of `value`.
  r@   r9   r   4Incompatible tensor conversion requested to `dtype` z for `value` () with dtype .)rx   r	   EagerTensorr   executing_eagerlyconvert_to_tensorr   NativeObjectr   rg   is_compatible_withr@   
ValueErrorr9   r   s       r   r   r   .  s    0 s'0I0I0K  e$vNN%../V__U+>>u{{K
@__U#(()w ?kkq"# # L  e$vNNr   c           	          t        | t        j                        st        d      g }t	        |       D ]B  \  }}||j                  |       |dnd||fz  }|j                  t        ||||             D |S )au  Converts `values` to a list of `Tensor` or `IndexedSlices` objects.

  Any `IndexedSlices` or `SparseTensor` objects in `values` are returned
  unmodified.

  Args:
    values: An iterable of `None`, `IndexedSlices`, `SparseTensor`, or objects
      that can be consumed by `convert_to_tensor()`.
    dtype: (Optional.) The required `DType` of the returned `Tensor` or
      `IndexedSlices`.
    name: (Optional.) A name prefix to used when a new `Tensor` is created, in
      which case element `i` will be given the name `name + '_' + i`.
    as_ref: True if the caller wants the results as ref tensors.

  Returns:
    A list of `Tensor`, `IndexedSlices`, `SparseTensor` and/or `None` objects.

  Raises:
    TypeError: If no conversion function is registered for an element in
      `values`.
    RuntimeError: If a registered conversion function returns an invalid
      value.
  z#Argument `values` must be iterable.Nz%s_%dr   )rx   r   Iterable	TypeError	enumeratern   r   )r,   r@   r9   r   retir   ns           r   .internal_convert_n_to_tensor_or_indexed_slicesr   T  s    6 
FO44	5
9
::
#F# :ha}	jj,$GtQi$7a	jj
65q9:: 
*r   c                      t        | ||d      S )a%  Converts `values` to a list of `Output` or `IndexedSlices` objects.

  Any `IndexedSlices` or `SparseTensor` objects in `values` are returned
  unmodified.

  Args:
    values: A list of `None`, `IndexedSlices`, `SparseTensor`, or objects that
      can be consumed by `convert_to_tensor()`.
    dtype: (Optional.) The required `DType` of the returned `Tensor`
      `IndexedSlices`.
    name: (Optional.) A name prefix to used when a new `Tensor` is created, in
      which case element `i` will be given the name `name + '_' + i`.

  Returns:
    A list of `Tensor`, `IndexedSlices`, and/or `SparseTensor` objects.

  Raises:
    TypeError: If no conversion function is registered for an element in
      `values`.
    RuntimeError: If a registered conversion function returns an invalid
      value.
  F)r,   r@   r9   r   )r   )r,   r@   r9   s      r   %convert_n_to_tensor_or_indexed_slicesr   }  s    . 
85tE
; ;r   i c                 "   |}|rM|j                  | j                        s2t        d|j                   d|  d| j                  j                         | j                  t        d|       t        j                         sWt        j                  | j                        }|6t        j                  |      }|t        k\  rt        j                  d|z         t        j                  | j                   | j"                  | j                  d   |      S )a  Converts an IndexedSlices object `value` to a Tensor.

  NOTE(mrry): This function is potentially expensive.

  Args:
    value: An ops.IndexedSlices object.
    dtype: The dtype of the Tensor to be returned.
    name: Optional name to use for the returned Tensor.
    as_ref: True if a ref is requested.

  Returns:
    A dense Tensor representing the values in the given IndexedSlices.

  Raises:
    ValueError: If the IndexedSlices does not have the same dtype.
  r   z for IndexedSlices (r   zXTensor conversion requested for IndexedSlices for argument `value` without dense_shape: znConverting sparse IndexedSlices to a dense Tensor with %d elements. This may consume a large amount of memory.r   )r9   )r   r@   r   r9   r.   r   r   r   constant_valuery   prod_LARGE_SPARSE_NUM_ELEMENTSwarningswarnr   unsorted_segment_sumr,   r-   )r   r@   r9   r   _dense_shape_valuenum_elementss          r   _indexed_slices_to_tensorr     s   " !
5++EKK8

>uzzl Kekk.>.>-?	AB B 
	  %y	*+ +
 
	"	"	$#2253D3DE$WW./l	3	3C	 
	*	*llEMM5#4#4Q#7d
D Dr   )NN)NNF)3r%   collectionsr   numpyry   tensorflow.core.protobufr   tensorflow.pythonr   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   r	   r
   r   r   r   r   tensorflow.python.opsr   tensorflow.python.saved_modelr   tensorflow.python.typesr   tensorflow.python.util.compatr    tensorflow.python.util.tf_exportr   CompositeTensorGradientr   r&   r   CompositeTensor
namedtupler[   TypeSpecrN   register_codecBuiltInTypeSpecCodecTypeSpecProtoINDEXED_SLICES_SPECr   r   r   r   r   r   #register_tensor_conversion_functionr   r   r   <module>r      s~       / ! + 8 A . + B 4 3 3 1 . @ , 9 655 ?M$$M M` ,[++>@  ?)	** ?)  ?)D &  % %///:33GG 4569 792 8<6:8=#ON :>8<:?&R;: ' &DR ?  > >,.r   