B
    ٻdDP                 @   s  d Z ddl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 edgdedddd Zedgdedddd Zedgdedddd Zedgdeddd d! Z dBd"d#Z!d$d% Z"d&d' Z#d(d) Z$d*d+ Z%d,d- Z&d.d/ Z'd0d1 Z(d2d3 Z)d4d5 Z*d6d7 Z+d8d9 Z,dCd;d<Z-G d=d> d>ej.Z/e0d?G d@dA dAej1Z2e3e4de2j5 dS )Dz;Utilities for describing the structure of a `tf.data` type.    N)nest)composite_tensor)ops)sparse_tensor)tensor_shape)tensor_spec)	type_spec)resource_variable_ops)tensor_array_ops)ragged_tensor)
tf_logging)deprecation)collections_abc)	tf_exportz!data.experimental.TensorStructure)Zv1zUse `tf.TensorSpec` instead.c             C   s   t || S )N)r   
TensorSpec)dtypeshape r   W/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/data/util/structure.py_TensorStructure'   s    r   z'data.experimental.SparseTensorStructurez"Use `tf.SparseTensorSpec` instead.c             C   s   t || S )N)r   SparseTensorSpec)r   r   r   r   r   _SparseTensorStructure-   s    r   z&data.experimental.TensorArrayStructurez!Use `tf.TensorArraySpec` instead.c             C   s   t || ||S )N)r
   TensorArraySpec)r   Zelement_shapedynamic_sizeinfer_shaper   r   r   _TensorArrayStructure3   s    r   z'data.experimental.RaggedTensorStructurez"Use `tf.RaggedTensorSpec` instead.c             C   s   t || |S )N)r   RaggedTensorSpec)r   r   Zragged_rankr   r   r   _RaggedTensorStructure:   s    r   c             C   s  g }|dkr*t | }dgt| }| }nt |}t || }|}tdl ddlm} xVtt	||D ]B\}\}}	y|	dkrt
|dd}	W n, tk
r   |tj|d| d Y qpX t|	tjr|tj| qpt|	tjr|tj|d| d qpt|	tj|jfr,|| qpt|	trF|t  qpt|	tjrt|tj|d	| |	jd
 qpt|tjr|| qpt |	dd}
|tj|d| |
d
 qpW W dQ R X t !||S )a  Normalizes a nested structure of element components.

  * Components matching `SparseTensorSpec` are converted to `SparseTensor`.
  * Components matching `RaggedTensorSpec` are converted to `RaggedTensor`.
  * Components matching `VariableSpec` are converted to `Tensor`.
  * Components matching `DatasetSpec` or `TensorArraySpec` are passed through.
  * `CompositeTensor` components are passed through.
  * All other components are converted to `Tensor`.

  Args:
    element: A nested structure of individual components.
    element_signature: (Optional.) A nested structure of `tf.DType` objects
      corresponding to each component of `element`. If specified, it will be
      used to set the exact type of output tensor when converting input
      components which are not tensors themselves (e.g. numpy arrays, native
      python types, etc.)

  Returns:
    A nested structure of `Tensor`, `Variable`, `Dataset`, `SparseTensor`,
    `RaggedTensor`, or `TensorArray` objects.
  Nnormalize_elementr   )dataset_opsF)use_fallbackzcomponent_%d)nameZ
component_)r!   r   r   )"r   flattenlenZflatten_up_tor   Z
name_scopeZtensorflow.python.data.opsr   	enumerateziptype_spec_from_value	TypeErrorappendconvert_to_tensor
isinstancer   r   SparseTensor
from_valuer   r   Z"convert_to_tensor_or_ragged_tensorr
   r   ZDatasetSpecNoneTensorSpec
NoneTensorr	   ZVariableSpecr   r   CompositeTensorgetattrpack_sequence_as)elementZelement_signatureZnormalized_components
componentsZflattened_signatureZpack_asr   itspecr   r   r   r   r   C   sJ    

 $r   c       
      C   s   t | }t |}t |}g }xt|||D ]\}}}	t|	tjrR||	 q0t|	tj	rr|t
|| q0t|	tjr|t|| q0t|	tjr|tj|dd |t|d t|d d q0td|	jq0W t ||S )a  Returns a `Structure` that represents the given legacy structure.

  This method provides a way to convert from the existing `Dataset` and
  `Iterator` structure-related properties to a `Structure` object. A "legacy"
  structure is represented by the `tf.data.Dataset.output_types`,
  `tf.data.Dataset.output_shapes`, and `tf.data.Dataset.output_classes`
  properties.

  TODO(b/110122868): Remove this function once `Structure` is used throughout
  `tf.data`.

  Args:
    output_types: A nested structure of `tf.DType` objects corresponding to
      each component of a structured value.
    output_shapes: A nested structure of `tf.TensorShape` objects
      corresponding to each component a structured value.
    output_classes: A nested structure of Python `type` objects corresponding
      to each component of a structured value.

  Returns:
    A `Structure`.

  Raises:
    TypeError: If a structure cannot be built from the arguments, because one of
      the component classes in `output_classes` is not supported.
     Nr      )r   r   zCould not build a structure for output class {}. Make sure any component class in `output_classes` inherits from one of the following classes: `tf.TypeSpec`, `tf.sparse.SparseTensor`, `tf.Tensor`, `tf.TensorArray`.)r   r"   r%   r*   r   ZTypeSpecr(   
issubclassr   r+   r   r   ZTensorr   r   r
   ZTensorArrayr   r   Zdimension_valuer'   format__name__r1   )
Zoutput_typesZoutput_shapesZoutput_classesZ
flat_typesZflat_shapesZflat_classesflat_retZ	flat_typeZ
flat_shapeZ
flat_classr   r   r   convert_legacy_structure   s,    


r=   c       
      C   s   t |}dd |D }t|t|kr@tdt|t|d}g }x>t||D ]0\}}||||  }	|| ||	 ||7 }qTW t ||S )a]  Returns an element constructed from the given spec and tensor list.

  Args:
    decode_fn: Method that constructs an element component from the element spec
      component and a tensor list.
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.
    tensor_list: A list of tensors to use for constructing the value.

  Returns:
    An element constructed from the given spec and tensor list.

  Raises:
    ValueError: If the number of tensors needed to construct an element for
      the given spec does not match the given number of tensors.
  c             S   s   g | ]}t |jqS r   )r#   _flat_tensor_specs).0r6   r   r   r   
<listcomp>   s    z,_from_tensor_list_helper.<locals>.<listcomp>zExpected {} tensors but got {}.r   )	r   r"   sumr#   
ValueErrorr:   r%   r(   r1   )
Z	decode_fnelement_spectensor_listZ
flat_specsZflat_spec_lengthsr4   r<   Zcomponent_specZnum_flat_valuesvaluer   r   r   _from_tensor_list_helper   s    
rF   c             C   s   t dd | |S )a  Returns an element constructed from the given spec and tensor list.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.
    tensor_list: A list of tensors to use for constructing the value.

  Returns:
    An element constructed from the given spec and tensor list.

  Raises:
    ValueError: If the number of tensors needed to construct an element for
      the given spec does not match the given number of tensors.
  c             S   s
   |  |S )N)Z_from_compatible_tensor_list)r6   rE   r   r   r   <lambda>       z-from_compatible_tensor_list.<locals>.<lambda>)rF   )rC   rD   r   r   r   from_compatible_tensor_list   s    rI   c             C   s   t dd | |S )a(  Returns an element constructed from the given spec and tensor list.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.
    tensor_list: A list of tensors to use for constructing the value.

  Returns:
    An element constructed from the given spec and tensor list.

  Raises:
    ValueError: If the number of tensors needed to construct an element for
      the given spec does not match the given number of tensors or the given
      spec is not compatible with the tensor list.
  c             S   s
   |  |S )N)Z_from_tensor_list)r6   rE   r   r   r   rG     rH   z"from_tensor_list.<locals>.<lambda>)rF   )rC   rD   r   r   r   from_tensor_list   s    rJ   c             C   s    t tjdd t| D S )a  Returns a list `tf.TypeSpec`s for the element tensor representation.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.

  Returns:
    A list `tf.TypeSpec`s for the element tensor representation.
  c             s   s   | ]}|j V  qd S )N)r>   )r?   r6   r   r   r   	<genexpr>!  s    z(get_flat_tensor_specs.<locals>.<genexpr>)list	itertoolschainfrom_iterabler   r"   )rC   r   r   r   get_flat_tensor_specs  s    rP   c             C   s   dd t | D S )a  Returns a list `tf.TensorShapes`s for the element tensor representation.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.

  Returns:
    A list `tf.TensorShapes`s for the element tensor representation.
  c             S   s   g | ]
}|j qS r   )r   )r?   r6   r   r   r   r@   .  s    z*get_flat_tensor_shapes.<locals>.<listcomp>)rP   )rC   r   r   r   get_flat_tensor_shapes$  s    
rQ   c             C   s   dd t | D S )a  Returns a list `tf.DType`s for the element tensor representation.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.

  Returns:
    A list `tf.DType`s for the element tensor representation.
  c             S   s   g | ]
}|j qS r   )r   )r?   r6   r   r   r   r@   ;  s    z)get_flat_tensor_types.<locals>.<listcomp>)rP   )rC   r   r   r   get_flat_tensor_types1  s    
rR   c                s8   t ||  fdd}t|tt |t |g S )a  Returns a tensor list representation of the element.

  Args:
    encode_fn: Method that constructs a tensor list representation from the
      given element spec and element.
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.
    element: The element to convert to tensor list representation.

  Returns:
    A tensor list representation of `element`.

  Raises:
    ValueError: If `element_spec` and `element` do not have the same number of
      elements or if the two structures are not nested in the same way.
    TypeError: If `element_spec` and `element` differ in the type of sequence
      in any of their substructures.
  c                s   |\}} | ||S )Nr   )staterE   r6   	component)	encode_fnr   r   	reduce_fnT  s    z)_to_tensor_list_helper.<locals>.reduce_fn)r   assert_same_structure	functoolsreducer%   r"   )rU   rC   r2   rV   r   )rU   r   _to_tensor_list_helper>  s    rZ   c             C   s   t dd | |S )a  Returns a tensor list representation of the element.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.
    element: The element to convert to tensor list representation.

  Returns:
    A tensor list representation of `element`.

  Raises:
    ValueError: If `element_spec` and `element` do not have the same number of
      elements or if the two structures are not nested in the same way or the
      rank of any of the tensors in the tensor list representation is 0.
    TypeError: If `element_spec` and `element` differ in the type of sequence
      in any of their substructures.
  c             S   s   | | | S )N)_to_batched_tensor_list)rS   r6   rT   r   r   r   rG   r  s   z(to_batched_tensor_list.<locals>.<lambda>)rZ   )rC   r2   r   r   r   to_batched_tensor_list\  s    r\   c             C   s   t dd | |S )aC  Returns a tensor list representation of the element.

  Args:
    element_spec: A nested structure of `tf.TypeSpec` objects representing to
      element type specification.
    element: The element to convert to tensor list representation.

  Returns:
    A tensor list representation of `element`.

  Raises:
    ValueError: If `element_spec` and `element` do not have the same number of
      elements or if the two structures are not nested in the same way.
    TypeError: If `element_spec` and `element` differ in the type of sequence
      in any of their substructures.
  c             S   s   | | | S )N)_to_tensor_list)rS   r6   rT   r   r   r   rG     rH   z to_tensor_list.<locals>.<lambda>)rZ   )rC   r2   r   r   r   to_tensor_listv  s    r^   c             C   sx   yt | | W n& tk
r$   dS  tk
r6   dS X x:tt | t |D ] \}}||rl||sPdS qPW dS )a  Indicates whether two type specifications are compatible.

  Two type specifications are compatible if they have the same nested structure
  and the their individual components are pair-wise compatible.

  Args:
    spec1: A `tf.TypeSpec` object to compare.
    spec2: A `tf.TypeSpec` object to compare.

  Returns:
    `True` if the two type specifications are compatible and `False` otherwise.
  FT)r   rW   r'   rB   r%   r"   Zis_compatible_with)Zspec1Zspec2s1s2r   r   r   are_compatible  s     ra   Tc          
      s  t  }|dk	r|S t tjrZt tjr< fdd}nt }|dd   D S t t	rt
 drt jtjrtdd  jD rt tjrt j}nt }|d	d  D  S t	d
d  D S t
 jdrt jd}t  fdd|D  S |rvy$t }t|}|dk	r0|S W nB ttfk
rt } ztddt j|f  W dd}~X Y nX td t jdS )a  Creates a type specification for the given value.

  Args:
    element: The element to create the type specification for.
    use_fallback: Whether to fall back to converting the element to a tensor
      in order to compute its `TypeSpec`.

  Returns:
    A nested structure of `TypeSpec`s that represents the type specification
    of `element`.

  Raises:
    TypeError: If a `TypeSpec` cannot be built for `element`, because its type
      is not supported.
  Nc                s   t   j| S )N)typedefault_factory)items)r2   r   r   rG     rH   z&type_spec_from_value.<locals>.<lambda>c             S   s   g | ]\}}|t |fqS r   )r&   )r?   kvr   r   r   r@     s    z(type_spec_from_value.<locals>.<listcomp>_fieldsc             s   s   | ]}t |tV  qd S )N)r*   str)r?   fr   r   r   rK     s    z'type_spec_from_value.<locals>.<genexpr>c             S   s   g | ]}t |qS r   )r&   )r?   rf   r   r   r   r@     s    c             S   s   g | ]}t |qS r   )r&   )r?   rf   r   r   r   r@     s    Z__attrs_attrs__c                s   g | ]}t t |jqS r   )r&   r0   r!   )r?   a)r2   r   r   r@     s       z"Failed to convert %r to tensor: %sz0Could not build a `TypeSpec` for {} with type {})r   Z_type_spec_from_valuer*   r   Mappingcollectionsdefaultdictrb   rd   tuplehasattrrg   SequenceallwraptZObjectProxy__wrapped__	__class__r0   r   r)   r&   rB   r'   loggingZvlogr;   r:   )r2   r    r6   ZctorZelement_typeattrsZtensorer   )r2   r   r&     sB    



(r&   c               @   s   e Zd ZdZedd ZdS )r.   z1Composite tensor representation for `None` value.c             C   s   t  S )N)r-   )selfr   r   r   
_type_spec  s    zNoneTensor._type_specN)r;   
__module____qualname____doc__propertyrz   r   r   r   r   r.     s   r.   ztf.NoneTensorSpecc               @   s   e Zd ZdZedd Zdd Zedd Zdd	 Zd
d Z	dd Z
edd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )r-   z$Type specification for `None` value.c             C   s   t S )N)r.   )ry   r   r   r   
value_type   s    zNoneTensorSpec.value_typec             C   s   dS )Nr   r   )ry   r   r   r   
_serialize  s    zNoneTensorSpec._serializec             C   s   g S )Nr   )ry   r   r   r   _component_specs  s    zNoneTensorSpec._component_specsc             C   s   g S )Nr   )ry   rE   r   r   r   _to_components  s    zNoneTensorSpec._to_componentsc             C   s   d S )Nr   )ry   r3   r   r   r   _from_components  s    zNoneTensorSpec._from_componentsc             C   s   g S )Nr   )ry   rE   r   r   r   r]     s    zNoneTensorSpec._to_tensor_listc             C   s   t  S )N)r-   )rE   r   r   r   r,     s    zNoneTensorSpec.from_valuec             C   s   t  S )N)r-   )ry   Z
batch_sizer   r   r   _batch  s    zNoneTensorSpec._batchc             C   s   t  S )N)r-   )ry   r   r   r   _unbatch  s    zNoneTensorSpec._unbatchc             C   s   g S )Nr   )ry   rE   r   r   r   r[     s    z&NoneTensorSpec._to_batched_tensor_listc             C   s   | S )Nr   )ry   r   r   r   _to_legacy_output_types!  s    z&NoneTensorSpec._to_legacy_output_typesc             C   s   | S )Nr   )ry   r   r   r   _to_legacy_output_shapes$  s    z'NoneTensorSpec._to_legacy_output_shapesc             C   s   | S )Nr   )ry   r   r   r   _to_legacy_output_classes'  s    z(NoneTensorSpec._to_legacy_output_classesc             C   s$   t | t |k	r td| || S )Nz/No `TypeSpec` is compatible with both {} and {})rb   rB   r:   )ry   otherr   r   r   most_specific_compatible_shape*  s    
z-NoneTensorSpec.most_specific_compatible_shapeN)r;   r{   r|   r}   r~   r   r   r   r   r   r]   staticmethodr,   r   r   r[   r   r   r   r   r   r   r   r   r-     s   r-   )N)T)6r}   rm   rX   rM   rs   Ztensorflow.python.data.utilr   Ztensorflow.python.frameworkr   r   r   r   r   r   Ztensorflow.python.opsr	   r
   Ztensorflow.python.ops.raggedr   Ztensorflow.python.platformr   rv   Ztensorflow.python.utilr   Ztensorflow.python.util.compatr   Z tensorflow.python.util.tf_exportr   
deprecatedr   r   r   r   r   r=   rF   rI   rJ   rP   rQ   rR   rZ   r\   r^   ra   r&   r/   r.   registerZBatchableTypeSpecr-   Z'register_type_spec_from_value_converterrb   r,   r   r   r   r   <module>   sX   




C;#
H

4
