o
    ?e4A                     @   s  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 dejZ edG dd dej!ej"ej#Z!e$dg dZ%edG dd dej&Z'e(e)e'ej*j+ edgdd)ddZ,			d*d d!Z-			d*d"d#Z.d)d$d%Z/d&Z0d*d'd(Z1e2e!e1 dS )+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                   @   s    e Zd ZdZdd Zdd ZdS )$IndexedSlicesCompositeTensorGradientz*CompositeTensorGradient for IndexedSlices.c                 C   s   |S N selfvaluer   r   k/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/framework/indexed_slices.pyget_gradient_components.      z<IndexedSlicesCompositeTensorGradient.get_gradient_componentsc                 C   s   |S r   r   )r   r   Zcomponent_gradsr   r   r   replace_gradient_components1   r   z@IndexedSlicesCompositeTensorGradient.replace_gradient_componentsN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   *   s    r   IndexedSlicesc                   @   s   e Zd ZdZd!ddZedd Zedd Zed	d
 Zedd Z	edd Z
edd Zedd Zedd Zedd Zdd Zdd Ze Zedd Zdd Zdd  ZdS )"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                 C   s   || _ || _|| _dS )zCreates an `IndexedSlices`.N)_values_indices_dense_shape)r   valuesindicesdense_shaper   r   r   __init__b   s   
zIndexedSlices.__init__c                 C      | j S )z/A `Tensor` containing the values of the slices.)r"   r   r   r   r   r%   h      zIndexedSlices.valuesc                 C   r)   )z4A 1-D `Tensor` containing the indices of the slices.)r#   r*   r   r   r   r&   m   r+   zIndexedSlices.indicesc                 C   r)   )zFA 1-D `Tensor` containing the shape of the corresponding dense tensor.)r$   r*   r   r   r   r'   r   r+   zIndexedSlices.dense_shapec                 C   s    | j du r
tdS t| 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_shaper*   r   r   r   shapew   s   

zIndexedSlices.shapec                 C      | j jS )z!The name of this `IndexedSlices`.)r%   namer*   r   r   r   r0         zIndexedSlices.namec                 C   r/   )zEThe name of the device on which `values` will be produced, or `None`.)r%   devicer*   r   r   r   r2      r1   zIndexedSlices.devicec                 C   r/   )z4The `Operation` that produces `values` as an output.)r%   opr*   r   r   r   r3      r1   zIndexedSlices.opc                 C   r/   )z'The `DType` of elements in this tensor.)r%   dtyper*   r   r   r   r4      r1   zIndexedSlices.dtypec                 C   r/   )zAThe `Graph` that contains the values, indices, and shape tensors.)r"   graphr*   r   r   r   r5      r1   zIndexedSlices.graphc                 C   s,   d| j | j| jd urd| jf f S df S )Nz&IndexedSlices(indices=%s, values=%s%s)z, dense_shape=%s )r#   r"   r$   r*   r   r   r   __str__   s   zIndexedSlices.__str__c                 C   s   t | j | j| jS r   )r!   r%   r&   r'   r*   r   r   r   __neg__   s   zIndexedSlices.__neg__c                 C   sx   | j j| jjd d }td g| jjdd  }| jd ur/| jj}|t	
| j}nd }t|| j| j j||S N   )r#   r.   Z
merge_withr"   r
   r,   concatenater$   r4   r   r-   IndexedSlicesSpec)r   indices_shaper'   dense_shape_dtyper   r   r   
_type_spec   s   

zIndexedSlices._type_specc                 C   sT   |d d }t d g|dd  }| jd u rd }n| jj}t|| j| jj||S r9   )r
   r,   r;   r$   r4   r<   r#   )r   r.   r=   r'   r>   r   r   r   _shape_invariant_to_type_spec   s   
z+IndexedSlices._shape_invariant_to_type_specc                 C   s   |   S r   )Z
_consumersr*   r   r   r   	consumers   s   zIndexedSlices.consumersr   )r   r   r   r    r(   propertyr%   r&   r'   r.   r0   r2   r3   r4   r5   r7   r8   r   Z__composite_gradient__r?   r@   rA   r   r   r   r   r!   6   s8    
'









IndexedSlicesValue)r%   r&   r'   r<   c                   @   s`   e Zd ZdZg dZedd Zdejej	ddfddZ
dd	 Zed
d Zdd Zdd ZdS )r<   z,Type specification for a `tf.IndexedSlices`._shape_values_dtype_indices_dtype_dense_shape_dtype_indices_shapec                 C   s   t S r   )r!   r*   r   r   r   <lambda>   s    zIndexedSlicesSpec.<lambda>Nc                 C   sV   t || _t|| _t|| _|du rd| _nt|| _t |d| _	dS )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`.
    Nr:   )
r
   Zas_shaperE   r   as_dtyperF   rG   rH   Z	with_rankrI   )r   r.   r4   Zindices_dtyper>   r=   r   r   r   r(      s   zIndexedSlicesSpec.__init__c                 C   s   | j | j| j| j| jfS r   rD   r*   r   r   r   
_serialize   s   zIndexedSlicesSpec._serializec                 C   s`   | j | jdd  }t|| jt| j | jg}| jd ur,|t| jj	g| j t
|S r9   )rI   r;   rE   r   Z
TensorSpecrF   rG   rH   appendZndimstuple)r   Zvalue_shapespecsr   r   r   _component_specs   s   
z"IndexedSlicesSpec._component_specsc                 C   s&   |j d u r|j|jfS |j|j|j fS r   )r'   r%   r&   r   r   r   r   _to_components   s   
z IndexedSlicesSpec._to_componentsc                 C   sJ   t dd |D r!t s!t|dkrt|d |d d S t| S t| S )Nc                 s   s    | ]	}t |tjV  qd S r   )
isinstancenpZndarray).0tr   r   r   	<genexpr>  s    z5IndexedSlicesSpec._from_components.<locals>.<genexpr>   r   r:   )allr   enabledlenrC   r!   )r   Ztensor_listr   r   r   _from_components  s   z"IndexedSlicesSpec._from_components)r   r   r   r    	__slots__rB   Z
value_typer   Zfloat32Zint64r(   rL   rP   rQ   r[   r   r   r   r   r<      s    


#convert_to_tensor_or_indexed_slices)v1c                 C      t | ||d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   r4   r0   as_ref),internal_convert_to_tensor_or_indexed_slices)r   r4   r0   r   r   r   r]     s   Fc                 C   s   t | tjrt stj| |||dS t | tjr:|r8t	|
| js8tdt	|j d|  d| jj d| S tj| |||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.
    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`.
  r4   r0   ra   4Incompatible tensor conversion requested to `dtype` z for `value` () with dtype .)rR   r   ZEagerTensorr   executing_eagerlyZconvert_to_tensorr   NativeObjectr   rK   is_compatible_withr4   
ValueErrorr0   r`   r   r   r   rb   .  s   
rb   c              	   C   sp   t | tjs
tdg }t| D ]%\}}|du r|| q|du r$dnd||f }|t||||d q|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_%drc   )rR   r   Iterable	TypeError	enumeraterM   rb   )r%   r4   r0   ra   retir   nr   r   r   .internal_convert_n_to_tensor_or_indexed_slicesT  s   rq   c                 C   r_   )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%   r4   r0   ra   )rq   )r%   r4   r0   r   r   r   %convert_n_to_tensor_or_indexed_slices}  s   rr   i c                 C   s   |}|r| | jstd|j d|  d| jj | jdu r&td| t sDt| j}|durDt	
|}|tkrDtd|  tj| j| j| jd |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.
  rd   z for IndexedSlices (re   NzXTensor 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   )r0   )ri   r4   rj   r0   r'   r   rg   r   Zconstant_valuerS   prod_LARGE_SPARSE_NUM_ELEMENTSwarningswarnr   Zunsorted_segment_sumr%   r&   )r   r4   r0   ra   _Zdense_shape_valueZnum_elementsr   r   r   _indexed_slices_to_tensor  s8   


rx   )NN)NNF)3r    collectionsru   numpyrS   Ztensorflow.core.protobufr   Ztensorflow.pythonr   Ztensorflow.python.eagerr   Ztensorflow.python.frameworkr   r   r   r   r	   r
   r   r   r   Ztensorflow.python.opsr   Ztensorflow.python.saved_modelr   Ztensorflow.python.typesr   Ztensorflow.python.util.compatr   Z tensorflow.python.util.tf_exportr   ZCompositeTensorGradientr   r!   rh   ZCompositeTensor
namedtuplerC   ZTypeSpecr<   Zregister_codecZBuiltInTypeSpecCodecZTypeSpecProtoZINDEXED_SLICES_SPECr]   rb   rq   rr   rt   rx   Z#register_tensor_conversion_functionr   r   r   r   <module>   sr   

 B

'

)
)