
    BVh              	       2   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 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l0m1Z1 dZ2d Z3dZ4d!Z5d"Z6d# Z7 e
jp                  d$       e1d%g&       G d' d(e)jr                                      Z:da; ejx                         Z=d) Z> e1d%g &       G d* d+e/jt                  e)jr                  ej~                  ej                  ,             ZA e
jp                  d$       G d- d.eA             ZB e1d/g &       G d0 d1ej                               ZD G d2 d3e+j                        ZF e&j                   e&j                  eDej                  j                                e-j                  dd4       e1d5      d6               ZL ej                          y)7zPython wrappers for Iterators.    N)
struct_pb2)ag_ctx)saveable_compat)iterator_autograph)optional_ops)options)nest)	structure)context)composite_tensor)dtypes)errors)ops)tensor)tensor_shape)	type_spec)
type_utils)array_ops_stack)gen_dataset_ops)parsing_ops)
string_ops)ragged_string_ops)nested_structure_coder)base)BaseSaverBuilder)deprecation)collections_abc)	tf_export    a  An unusually high number of `Iterator.get_next()` calls was detected. This often indicates that `Iterator.get_next()` is being called inside a training loop, which will cause gradual slowdown and eventual resource exhaustion. If this is the case, restructure your code to call `next_element = iterator.get_next()` once outside the loop, and use `next_element` as the input to some computation that is invoked inside the loop.zAn unusually high number of `tf.data.Iterator.get_next()` calls was detected. This suggests that the `for elem in dataset: ...` idiom is used within tf.function with AutoGraph disabled. This idiom is only supported when AutoGraph is enabled.	iteratorsc                      t        j                         r t        j                          j                  d u S t        j                         j
                  } t        |        S N)r   executing_eagerlydevice_namer   get_default_graph _device_functions_outer_to_innerbool)device_stacks    W/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/data/ops/iterator_ops.py_device_stack_is_emptyr*   U   sH     ??((D00&&(II,,	    ITERATORzdata.Iterator)v1c                   B   e Zd ZdZd Ze	 	 	 dd       Ze	 	 dd       Zed        Z	ddZ
ddZd	 Zdd
Ze ej                  dd      d               Ze ej                  dd      d               Ze ej                  dd      d               Zed        Zd Zd Zy)Iteratorz6Represents the state of iterating through a `Dataset`.c           	         || _         || _        |||t        d|d|d|d      t        j                  |||      | _        t        j                  | j
                        | _        t        j                  | j
                        | _	        t        j                  | j                         | _        d| _        t        j                  t         | j                          y)a  Creates a new iterator from the given iterator resource.

    Note: Most users will not call this initializer directly, and will
    instead use `Dataset.make_initializable_iterator()` or
    `Dataset.make_one_shot_iterator()`.

    Args:
      iterator_resource: A `tf.resource` scalar `tf.Tensor` representing the
        iterator.
      initializer: A `tf.Operation` that should be run to initialize this
        iterator.
      output_types: A (nested) structure of `tf.DType` objects corresponding to
        each component of an element of this iterator.
      output_shapes: A (nested) structure of `tf.TensorShape` objects
        corresponding to each component of an element of this iterator.
      output_classes: A (nested) structure of Python `type` objects
        corresponding to each component of an element of this iterator.

    Raises:
      TypeError: If `output_types`, `output_shapes`, or `output_classes` is not
        specified.
    Nz{All of `output_types`, `output_shapes`, and `output_classes` must be specified to create an iterator. Got `output_types` = z, `output_shapes` = z, `output_classes` = .r   )_iterator_resource_initializer
ValueErrorr
   convert_legacy_structure_element_specget_flat_tensor_shapes_flat_tensor_shapesget_flat_tensor_types_flat_tensor_typesr   iterator_to_string_handle_string_handle_get_next_call_countr   add_to_collectionGLOBAL_ITERATORS)selfiterator_resourceinitializeroutput_typesoutput_shapesoutput_classess         r)   __init__zIterator.__init__c   s    0 0D#D 5!*- .,/ 0  .1	45 5 #;;m^5D(?? D'==D *CC!D !D*D,C,CDr+   Nc                    t        j                  t        j                  |       } |t        j                  d |       }n%t        j                  | t
        j                  |      }|t        j                  d |       }t        j                  | |       t        j                  | ||      }|d}t        j                  d|t        j                  |      t        j                  |            }t        |d| ||      S )a	  Creates a new, uninitialized `Iterator` with the given structure.

    This iterator-constructing method can be used to create an iterator that
    is reusable with many different datasets.

    The returned iterator is not bound to a particular dataset, and it has
    no `initializer`. To initialize the iterator, run the operation returned by
    `Iterator.make_initializer(dataset)`.

    The following is an example

    ```python
    iterator = Iterator.from_structure(tf.int64, tf.TensorShape([]))

    dataset_range = Dataset.range(10)
    range_initializer = iterator.make_initializer(dataset_range)

    dataset_evens = dataset_range.filter(lambda x: x % 2 == 0)
    evens_initializer = iterator.make_initializer(dataset_evens)

    # Define a model based on the iterator; in this example, the model_fn
    # is expected to take scalar tf.int64 Tensors as input (see
    # the definition of 'iterator' above).
    prediction, loss = model_fn(iterator.get_next())

    # Train for `num_epochs`, where for each epoch, we first iterate over
    # dataset_range, and then iterate over dataset_evens.
    for _ in range(num_epochs):
      # Initialize the iterator to `dataset_range`
      sess.run(range_initializer)
      while True:
        try:
          pred, loss_val = sess.run([prediction, loss])
        except tf.errors.OutOfRangeError:
          break

      # Initialize the iterator to `dataset_evens`
      sess.run(evens_initializer)
      while True:
        try:
          pred, loss_val = sess.run([prediction, loss])
        except tf.errors.OutOfRangeError:
          break
    ```

    Args:
      output_types: A (nested) structure of `tf.DType` objects corresponding to
        each component of an element of this dataset.
      output_shapes: (Optional.) A (nested) structure of `tf.TensorShape`
        objects corresponding to each component of an element of this dataset.
        If omitted, each component will have an unconstrainted shape.
      shared_name: (Optional.) If non-empty, this iterator will be shared under
        the given name across multiple sessions that share the same devices
        (e.g. when using a remote server).
      output_classes: (Optional.) A (nested) structure of Python `type` objects
        corresponding to each component of an element of this iterator. If
        omitted, each component is assumed to be of type `tf.Tensor`.

    Returns:
      An `Iterator`.

    Raises:
      TypeError: If the structures of `output_shapes` and `output_types` are
        not the same.
    Nc                 ,    t        j                  d       S r"   r   TensorShape_s    r)   <lambda>z)Iterator.from_structure.<locals>.<lambda>       L,,T2 r+   c                 "    t         j                  S r"   r   TensorrK   s    r)   rM   z)Iterator.from_structure.<locals>.<lambda>   
    FMM r+    )	containershared_namerC   rD   )r	   map_structurer   as_dtypemap_structure_up_tor   as_shapeassert_same_structurer
   r5   r   iterator_v2r9   r7   r/   )rC   rD   rU   rE   output_structurerA   s         r)   from_structurezIterator.from_structure   s    L %%foo|DL((
2LBm ..|/;/D/D/<>m ))*A<Pn|]; 99m^5k'33445EF66	 %t\="$ $r+   c                 8   t        j                  t        j                  |      }|t        j                  d |      }n%t        j                  |t
        j                  |      }|t        j                  d |      }t        j                  ||       t        j                  |||      }t        j                  | t        j                        } t        j                  | t        j                  |      t        j                   |            }t#        |d|||      S )a  Creates a new, uninitialized `Iterator` based on the given handle.

    This method allows you to define a "feedable" iterator where you can choose
    between concrete iterators by feeding a value in a `tf.Session.run` call.
    In that case, `string_handle` would be a `tf.compat.v1.placeholder`, and you
    would
    feed it with the value of `tf.data.Iterator.string_handle` in each step.

    For example, if you had two iterators that marked the current position in
    a training dataset and a test dataset, you could choose which to use in
    each step as follows:

    ```python
    train_iterator = tf.data.Dataset(...).make_one_shot_iterator()
    train_iterator_handle = sess.run(train_iterator.string_handle())

    test_iterator = tf.data.Dataset(...).make_one_shot_iterator()
    test_iterator_handle = sess.run(test_iterator.string_handle())

    handle = tf.compat.v1.placeholder(tf.string, shape=[])
    iterator = tf.data.Iterator.from_string_handle(
        handle, train_iterator.output_types)

    next_element = iterator.get_next()
    loss = f(next_element)

    train_loss = sess.run(loss, feed_dict={handle: train_iterator_handle})
    test_loss = sess.run(loss, feed_dict={handle: test_iterator_handle})
    ```

    Args:
      string_handle: A scalar `tf.Tensor` of type `tf.string` that evaluates to
        a handle produced by the `Iterator.string_handle()` method.
      output_types: A (nested) structure of `tf.DType` objects corresponding to
        each component of an element of this dataset.
      output_shapes: (Optional.) A (nested) structure of `tf.TensorShape`
        objects corresponding to each component of an element of this dataset.
        If omitted, each component will have an unconstrainted shape.
      output_classes: (Optional.) A (nested) structure of Python `type` objects
        corresponding to each component of an element of this iterator. If
        omitted, each component is assumed to be of type `tf.Tensor`.

    Returns:
      An `Iterator`.
    Nc                 ,    t        j                  d       S r"   rI   rK   s    r)   rM   z-Iterator.from_string_handle.<locals>.<lambda>%  rN   r+   c                 "    t         j                  S r"   rP   rK   s    r)   rM   z-Iterator.from_string_handle.<locals>.<lambda>+  rR   r+   )dtyperC   rD   )r	   rV   r   rW   rX   r   rY   rZ   r
   r5   r   convert_to_tensorstringr   iterator_from_string_handle_v2r9   r7   r/   )string_handlerC   rD   rE   r\   rA   s         r)   from_string_handlezIterator.from_string_handle   s    d %%foo|DL((
2LBm ..|/;/D/D/<>m ))*A<Pn|]; 99m^5))-v}}MM'FF445EF667GHJ %t\="$ $r+   c                 H    | j                   | j                   S t        d      )zA `tf.Operation` that should be run to initialize this iterator.

    Returns:
      A `tf.Operation` that should be run to initialize this iterator

    Raises:
      ValueError: If this iterator initializes itself automatically.
    zThe iterator does not have an initializer. This means it was likely created using `tf.data.Dataset.make_one_shot_iterator()`. For an initializable iterator, use `tf.data.Dataset.make_initializable_iterator()` instead.)r3   r4   r@   s    r)   rB   zIterator.initializer7  s3     $ EF Fr+   c           	         t        j                  |d      5 }t        j                  d |j                        }t        j                  d |j                        }t        j                  d |j                        }t        j
                  | j                  |       t        j
                  | j                  |       t        t        j                  | j                        t        j                  |            D ]%  \  }}||ust        d| j                  d|d       t        t        j                  | j                        t        j                  |            D ]&  \  }}	||	k7  st        d| j                  d	|d       t        t        j                  | j                        t        j                  |            D ]2  \  }
}|
j                  |      rt        d
| j                  d|d       	 ddd       t        j                  | j                        5  t        j                   |j"                  | j                  |      cddd       S # 1 sw Y   ^xY w# 1 sw Y   yxY w)a  Returns a `tf.Operation` that initializes this iterator on `dataset`.

    Args:
      dataset: A `Dataset` whose `element_spec` if compatible with this
        iterator.
      name: (Optional.) A name for the created operation.

    Returns:
      A `tf.Operation` that can be run to initialize this iterator on the given
      `dataset`.

    Raises:
      TypeError: If `dataset` and this iterator do not have a compatible
        `element_spec`.
    make_initializerc                 "    | j                         S r"   _to_legacy_output_typescomponent_specs    r)   rM   z+Iterator.make_initializer.<locals>.<lambda>a  s    !G!G!I r+   c                 "    | j                         S r"   _to_legacy_output_shapesro   s    r)   rM   z+Iterator.make_initializer.<locals>.<lambda>d  s    !H!H!J r+   c                 "    | j                         S r"   _to_legacy_output_classesro   s    r)   rM   z+Iterator.make_initializer.<locals>.<lambda>g  s    !I!I!K r+   zExpected output classes z% but got dataset with output classes r1   zExpected output types z# but got dataset with output types z'Expected output shapes compatible with z$ but got dataset with output shapes Nname)r   
name_scoper	   rV   element_specrZ   rC   rD   zipflattenrE   	TypeErroris_compatible_withcolocate_withr2   r   make_iterator_variant_tensor)r@   datasetrx   dataset_output_typesdataset_output_shapesdataset_output_classesiterator_classdataset_classiterator_dtypedataset_dtypeiterator_shapedataset_shapes               r)   rk   zIterator.make_initializerL  sw     
0	1 $PT "//
I


  #00
J


   $11
K


  
   !2!24HI
  !3!35JK+.
,,t**
+
,,-
.,0 J
'.- .()<)<(? @--C,FaIJ J	J ,/
,,t((
)4<<8L+M,O >
'.-]*&t'8'8&; <##7":!=> >> ,/
,,t))
*DLL#-%,& P
'.- 00?78J8J7M N44I3LAOP P	P=$PN 
		422	3 G**

!
!4#:#:GG GO$P $PNG Gs,   C*IA$I'A0II,III(c                    | xj                   dz  c_         | j                   t        kD  rt        j                  t               t        j                  | j                        5  t        j                  | j                  | j                  | j                  |      }t        j                  | j                  |      cddd       S # 1 sw Y   yxY w)a  Returns the next element.

    In graph mode, you should typically call this method *once* and use its
    result as the input to another computation. A typical loop will then call
    `tf.Session.run` on the result of that computation. The loop will terminate
    when the `Iterator.get_next()` operation raises
    `tf.errors.OutOfRangeError`. The following skeleton shows how to use
    this method when building a training loop:

    ```python
    dataset = ...  # A `tf.data.Dataset` object.
    iterator = dataset.make_initializable_iterator()
    next_element = iterator.get_next()

    # Build a TensorFlow graph that does something with each element.
    loss = model_function(next_element)
    optimizer = ...  # A `tf.compat.v1.train.Optimizer` object.
    train_op = optimizer.minimize(loss)

    with tf.compat.v1.Session() as sess:
      try:
        while True:
          sess.run(train_op)
      except tf.errors.OutOfRangeError:
        pass
    ```

    NOTE: It is legitimate to call `Iterator.get_next()` multiple times, e.g.
    when you are distributing different elements to multiple devices in a single
    step. However, a common pitfall arises when users call `Iterator.get_next()`
    in each iteration of their training loop. `Iterator.get_next()` adds ops to
    the graph, and executing each op allocates resources (including threads); as
    a consequence, invoking it in every iteration of a training loop causes
    slowdown and eventual resource exhaustion. To guard against this outcome, we
    log a warning when the number of uses crosses a fixed threshold of
    suspiciousness.

    Args:
      name: (Optional.) A name for the created operation.

    Returns:
      A (nested) structure of values matching `tf.data.Iterator.element_spec`.
       )rC   rD   rx   N)r=   GET_NEXT_CALL_WARNING_THRESHOLDwarningswarnGET_NEXT_CALL_WARNING_MESSAGEr   r   r2   r   iterator_get_nextr:   r8   r
   from_tensor_listr6   )r@   rx   flat_rets      r)   get_nextzIterator.get_next  s    X 	"  #BBmm12 
		422	3 F 22

!
!..00	h
 ''(:(:HEF F Fs   !ACCc           
      `   t        j                  | j                        5  t        j                  t        j                  | j                  t        j                  | j                        t        j                  | j                              | j                        cd d d        S # 1 sw Y   y xY wNrb   r   r   r2   r   _OptionalImplr   iterator_get_next_as_optionalr
   r9   rz   r7   ri   s    r)   get_next_as_optionalzIterator.get_next_as_optional      			422	3 :''

7
7%%$::4;L;LM%<<##%& (,'8'8:: : :   A:B$$B-c                 `    || j                   S t        j                  | j                  |      S )zReturns a string-valued `tf.Tensor` that represents this iterator.

    Args:
      name: (Optional.) A name for the created operation.

    Returns:
      A scalar `tf.Tensor` of type `tf.string`.
    rw   )r<   r   r;   r2   )r@   rx   s     r)   rf   zIterator.string_handle  s3     |   66

!
!. .r+   5Use `tf.compat.v1.data.get_output_classes(iterator)`.c                 D    t        j                  d | j                        S )  Returns the class of each component of an element of this iterator.

    The expected values are `tf.Tensor` and `tf.sparse.SparseTensor`.

    Returns:
      A (nested) structure of Python `type` objects corresponding to each
      component of an element of this dataset.
    c                 "    | j                         S r"   ru   ro   s    r)   rM   z)Iterator.output_classes.<locals>.<lambda>      ~GGI r+   r	   rV   r6   ri   s    r)   rE   zIterator.output_classes  #     I r+   4Use `tf.compat.v1.data.get_output_shapes(iterator)`.c                 D    t        j                  d | j                        S )Returns the shape of each component of an element of this iterator.

    Returns:
      A (nested) structure of `tf.TensorShape` objects corresponding to each
      component of an element of this dataset.
    c                 "    | j                         S r"   rr   ro   s    r)   rM   z(Iterator.output_shapes.<locals>.<lambda>      ~FFH r+   r   ri   s    r)   rD   zIterator.output_shapes  #     H r+   3Use `tf.compat.v1.data.get_output_types(iterator)`.c                 D    t        j                  d | j                        S )Returns the type of each component of an element of this iterator.

    Returns:
      A (nested) structure of `tf.DType` objects corresponding to each component
      of an element of this dataset.
    c                 "    | j                         S r"   rm   ro   s    r)   rM   z'Iterator.output_types.<locals>.<lambda>      ~EEG r+   r   ri   s    r)   rC   zIterator.output_types  #     G r+   c                     | j                   S )aV  The type specification of an element of this iterator.

    For more information,
    read [this guide](https://www.tensorflow.org/guide/data#dataset_structure).

    Returns:
      A (nested) structure of `tf.TypeSpec` objects matching the structure of an
      element of this iterator and specifying the type of individual components.
    r6   ri   s    r)   rz   zIterator.element_spec  s     r+   c                     t        j                  | j                  t        j                  j
                  j                        }d|iS N_STATE)r   serialize_iteratorr2   options_libExternalStatePolicyFAILvaluer@   serialized_iterators     r)   _serialize_to_tensorszIterator._serialize_to_tensors  s?    )<<'',,224 )**r+   c                     t        j                  | j                        5  t        j                  | j                  |d         gcd d d        S # 1 sw Y   y xY wr   r   r   r2   r   deserialize_iteratorr@   restored_tensorss     r)   _restore_from_tensorszIterator._restore_from_tensors  T    			422	3 @22

!
!#3H#=? @@ @ @   $AANNN)NNr"   )__name__
__module____qualname____doc__rF   staticmethodr]   rg   propertyrB   rk   r   r   rf   r   
deprecatedrE   rD   rC   rz   r   r    r+   r)   r/   r/   ^   s-    ?-E^ #'!%$([$ [$z  (,(,D$ D$L F F(:Gx8Ft	:. ;
CEE  ;
BD	D 	 ;
AC	C 	  +@r+   r/   c                 z    t         5  t        }t        dz  ad d d        dj                  |       S # 1 sw Y   xY w)Nr   z{}{})	_uid_lock_uid_counterformat)prefixuids     r)   _generate_shared_namer   (  s<     
CAL 
vs	##	 s   1:c                   |    e Zd ZdZej
                  d        Zej                  d        Zej                  d        Z	y)IteratorBasea  Represents an iterator of a `tf.data.Dataset`.

  `tf.data.Iterator` is the primary mechanism for enumerating elements of a
  `tf.data.Dataset`. It supports the Python Iterator protocol, which means
  it can be iterated over using a for-loop:

  >>> dataset = tf.data.Dataset.range(2)
  >>> for element in dataset:
  ...   print(element)
  tf.Tensor(0, shape=(), dtype=int64)
  tf.Tensor(1, shape=(), dtype=int64)

  or by fetching individual elements explicitly via `get_next()`:

  >>> dataset = tf.data.Dataset.range(2)
  >>> iterator = iter(dataset)
  >>> print(iterator.get_next())
  tf.Tensor(0, shape=(), dtype=int64)
  >>> print(iterator.get_next())
  tf.Tensor(1, shape=(), dtype=int64)

  In addition, non-raising iteration is supported via `get_next_as_optional()`,
  which returns the next element (if available) wrapped in a
  `tf.experimental.Optional`.

  >>> dataset = tf.data.Dataset.from_tensors(42)
  >>> iterator = iter(dataset)
  >>> optional = iterator.get_next_as_optional()
  >>> print(optional.has_value())
  tf.Tensor(True, shape=(), dtype=bool)
  >>> optional = iterator.get_next_as_optional()
  >>> print(optional.has_value())
  tf.Tensor(False, shape=(), dtype=bool)
  c                     t        d      )a  The type specification of an element of this iterator.

    >>> dataset = tf.data.Dataset.from_tensors(42)
    >>> iterator = iter(dataset)
    >>> iterator.element_spec
    tf.TensorSpec(shape=(), dtype=tf.int32, name=None)

    For more information,
    read [this guide](https://www.tensorflow.org/guide/data#dataset_structure).

    Returns:
      A (nested) structure of `tf.TypeSpec` objects matching the structure of an
      element of this iterator, specifying the type of individual components.
    zIterator.element_specNotImplementedErrorri   s    r)   rz   zIteratorBase.element_specY  s      5
66r+   c                     t        d      )ay  Returns the next element.

    >>> dataset = tf.data.Dataset.from_tensors(42)
    >>> iterator = iter(dataset)
    >>> print(iterator.get_next())
    tf.Tensor(42, shape=(), dtype=int32)

    Returns:
      A (nested) structure of values matching `tf.data.Iterator.element_spec`.

    Raises:
      `tf.errors.OutOfRangeError`: If the end of the iterator has been reached.
    zIterator.get_next()r   ri   s    r)   r   zIteratorBase.get_nextk  s     3
44r+   c                     t        d      )a  Returns the next element wrapped in `tf.experimental.Optional`.

    If the iterator has reached the end of the sequence, the returned
    `tf.experimental.Optional` will have no value.

    >>> dataset = tf.data.Dataset.from_tensors(42)
    >>> iterator = iter(dataset)
    >>> optional = iterator.get_next_as_optional()
    >>> print(optional.has_value())
    tf.Tensor(True, shape=(), dtype=bool)
    >>> print(optional.get_value())
    tf.Tensor(42, shape=(), dtype=int32)
    >>> optional = iterator.get_next_as_optional()
    >>> print(optional.has_value())
    tf.Tensor(False, shape=(), dtype=bool)

    Returns:
      A `tf.experimental.Optional` object representing the next element.
    zIterator.get_next_as_optional()r   ri   s    r)   r   z!IteratorBase.get_next_as_optional|  s    * ?
@@r+   N)
r   r   r   r   abcabstractpropertyrz   abstractmethodr   r   r   r+   r)   r   r   0  sX    !F 7 7" 5 5  A Ar+   r   )	metaclassc                   F    e Zd ZdZd fd	Zd Zd Zd Zd Zd Z	d	 Z
ed
        Zd Ze ej                  dd      d               Ze ej                  dd      d               Ze ej                  dd      d               Zed        Zd Zd Zd Zd Zd Zd Z xZS )OwnedIteratora^  An iterator producing tf.Tensor objects from a tf.data.Dataset.

  The iterator resource  created through `OwnedIterator` is owned by the Python
  object and the life time of the underlying resource is tied to the life time
  of the `OwnedIterator` object. This makes `OwnedIterator` appropriate for use
  in eager mode and inside of tf.functions.
  Nc                 h   t         t        |           |v||t        d      || _        t        j                  | j                        | _        t        j                  | j                        | _	        || _
        |\  | _        d| _        y||t        d      | j                  |       d| _        y)a'  Creates a new iterator from the given dataset.

    If `dataset` is not specified, the iterator will be created from the given
    tensor components and element structure. In particular, the alternative for
    constructing the iterator is used when the iterator is reconstructed from
    it `CompositeTensor` representation.

    Args:
      dataset: A `tf.data.Dataset` object.
      components: Tensor components to construct the iterator from.
      element_spec: A (nested) structure of `TypeSpec` objects that
        represents the type specification of elements of the iterator.

    Raises:
      ValueError: If `dataset` is not provided and either `components` or
        `element_spec` is not provided. Or `dataset` is provided and either
        `components` and `element_spec` is provided.
    NzWWhen `dataset` is not provided, both `components` and `element_spec` must be specified.zRWhen `dataset` is provided, `element_spec` and `components` must not be specified.r   )superr   rF   r4   r6   r
   r9   _flat_output_typesr7   _flat_output_shapes_componentsr2   _create_iteratorr=   )r@   r   
componentsrz   	__class__s       r)   rF   zOwnedIterator.__init__  s    & 
-')

 401 	1 (d ) ? ?


!d!*!A!A


"d#d!+d !"D 
 L$< ! 	! G$ !Dr+   c                 .   |j                         }|| _        |j                  }|j                  | _        t        j                  | j                        | _        t        j                  | j                        | _	        t        j                  |      5  t        j                  | j                  | j                        | _        t        j                          st#        j$                  | j                        }t'        |j(                  d   j(                  d   j(                        t'        | j                        k(  sJ | j                  j*                  j-                  |       t        j.                  || j                         d d d        y # 1 sw Y   y xY w)Nrb   r   )_apply_debug_options_datasetr   rz   r6   r
   r9   r   r7   r   r   r   r   anonymous_iterator_v3r2   r   r#   r   iterator_full_type_from_speclenargsopexperimental_set_typer   )r@   r   
ds_variantfulltypes       r)   r   zOwnedIterator._create_iterator  sU   **,G DM((J --D'==D(?? D			:	& I

/
/22 446  &&( ::  8==#((+001S##6% % 	% %""88B##J0G0GH'I I Is   C0FFc                     | S r"   r   ri   s    r)   __iter__zOwnedIterator.__iter__  s    Kr+   c                 "    | j                         S r"   )__next__ri   s    r)   nextzOwnedIterator.next  s    ==?r+   c                    t        j                         j                  }|t         j                  j                  k(  }t        j                         s9|r7| xj                  dz  c_        | j                  t        kD  rt        t              t        j                         st        j                  | j                        5  t        j                  | j                  | j                   | j"                        }t%        j&                  | j(                  |      cd d d        S t        j*                  t
        j,                        5  t        j                  | j                  | j                   | j"                        }	 | j(                  j/                  |      cd d d        S # 1 sw Y   xY w# t0        $ r, t%        j&                  | j(                  |      cY cd d d        S w xY w# 1 sw Y   y xY w)Nr   rb   )autograph_ctxcontrol_status_ctxstatusStatusDISABLEDr   r#   r=   GET_NEXT_CALL_ERROR_THRESHOLDr4   GET_NEXT_CALL_ERROR_MESSAGEr   r   r2   r   r   r   r   r
   from_compatible_tensor_listr6   execution_modeSYNC_from_compatible_tensor_listAttributeError)r@   autograph_statusautograph_disabledrets       r)   _next_internalzOwnedIterator._next_internal  s   $779@@)]-A-A-J-JJ$$&+=
1$		"	"%B	B455$$&T445 N//##00224 44T5G5GMN N 
			- 
N--

!
!..002c
N!!>>sC
N 
NN N$  N44T5G5GMM
N 
NN
N 
Ns7   <AF?7G7F'F$')GGGGG(c                     d }| j                   rR| j                   j                         j                  r.| j                   j                         j                  j                  }t	        j
                  | j                  |      }t        j                  |      }|D cg c]  }t        j                  |       }}t        j                  |      }t        j                  |      }t        j                  |d      }|S c c}w )N,)	separator)r   r   "experimental_external_state_policyr   r   r   r2   r   unstackr   serialize_tensorstackr   encode_base64string_join)r@   external_state_policystate_variantstatexs        r)   _savezOwnedIterator._save  s     MM!!#FF --


!
D
D
J
J  $66!6M
 ##M2E6;<[))!,<E<!!%(E$$U+E""5C8EL =s   C;c                 Z   t        j                  |d      }t        j                  |      }t	        j
                  |      }|D cg c]&  }t        j                  |t        j                        ( }}t	        j                  |      }t        j                  | j                  |      S c c}w )Nr  )sep)r   string_split_v2r   decode_base64r   r  r   parse_tensorr   variantr  r   r   r2   )r@   r  r  r  s       r)   _restorezOwnedIterator._restore)  s    --e=E$$U+E##E*EBGHQ[%%a8HEH#))%0M//  Is   +B(c                 ,    t        | j                        S r"   IteratorSpecrz   ri   s    r)   
_type_speczOwnedIterator._type_spec4  s    ))**r+   c                 ^    	 | j                         S # t        j                  $ r t        w xY wr"   )r  r   OutOfRangeErrorStopIterationri   s    r)   r   zOwnedIterator.__next__8  s1      ""!! s    ,r   c                 D    t        j                  d | j                        S )r   c                 "    | j                         S r"   ru   ro   s    r)   rM   z.OwnedIterator.output_classes.<locals>.<lambda>K  r   r+   r   ri   s    r)   rE   zOwnedIterator.output_classes>  r   r+   r   c                 D    t        j                  d | j                        S )r   c                 "    | j                         S r"   rr   ro   s    r)   rM   z-OwnedIterator.output_shapes.<locals>.<lambda>Y  r   r+   r   ri   s    r)   rD   zOwnedIterator.output_shapesN  r   r+   r   c                 D    t        j                  d | j                        S )r   c                 "    | j                         S r"   rm   ro   s    r)   rM   z,OwnedIterator.output_types.<locals>.<lambda>g  r   r+   r   ri   s    r)   rC   zOwnedIterator.output_types\  r   r+   c                     | j                   S r"   r   ri   s    r)   rz   zOwnedIterator.element_specj  s    r+   c                 "    | j                         S r"   )r  ri   s    r)   r   zOwnedIterator.get_nextn  s      r+   c           
      `   t        j                  | j                        5  t        j                  t        j                  | j                  t        j                  | j                        t        j                  | j                              | j                        cd d d        S # 1 sw Y   y xY wr   r   ri   s    r)   r   z"OwnedIterator.get_next_as_optionalq  r   r   c                    d }| j                   rt| j                   j                         j                  rPt        j                  | j
                  | j                   j                         j                  j                        }d|iS t        j                  | j
                  t        j                  j                  j                        }d|iS r   )
r   r   r  r   r   r2   r   r   r   r   r   s     r)   r   z#OwnedIterator._serialize_to_tensors|  s    BB+>>

!
!
--


!
D
D
J
JL )** ,>>

!
!

)
)
.
.
4
46 )**r+   c                     t        j                  | j                        5  t        j                  | j                  |d         gcd d d        S # 1 sw Y   y xY wr   r   r   s     r)   r   z#OwnedIterator._restore_from_tensors  r   r   c                     | |vrJ| j                   %t        | j                  | j                        || <   nt        | j                         || <   | j	                         }||    j                  |       y)z3Implements checkpointing protocols for `Trackable`.N)r   rz   )r   )r   r   r   r6   r   r   )r@   
object_map
serializeds      r)   _copy_trackable_to_cpuz$OwnedIterator._copy_trackable_to_cpu  so     :		(D4D4D6:6H6HJ
4 )?
4 ++-Jt**:6r+   c                     | j                   S r"   )r%  )r@   rL   s     r)   __tf_tracing_type__z!OwnedIterator.__tf_tracing_type__  s    ??r+   r   )r   r   r   r   rF   r   r   r   r  r  r!  r   r%  r   r   r   rE   rD   rC   rz   r   r   r   r   r7  r9  __classcell__r   s   @r)   r   r     s   )"V#IJN>,	 + + ;
CEE  ;
BD	D 	 ;
AC	C 	  !	:+@
7r+   r   zdata.IteratorSpecc                   ^    e Zd ZdZdgZd Zed        Zd Zed        Z	d Z
d Zed	        Zy
)r$  a  Type specification for `tf.data.Iterator`.

  For instance, `tf.data.IteratorSpec` can be used to define a tf.function that
  takes `tf.data.Iterator` as an input argument:

  >>> @tf.function(input_signature=[tf.data.IteratorSpec(
  ...   tf.TensorSpec(shape=(), dtype=tf.int32, name=None))])
  ... def square(iterator):
  ...   x = iterator.get_next()
  ...   return x * x
  >>> dataset = tf.data.Dataset.from_tensors(5)
  >>> iterator = iter(dataset)
  >>> print(square(iterator))
  tf.Tensor(25, shape=(), dtype=int32)

  Attributes:
    element_spec: A (nested) structure of `tf.TypeSpec` objects that represents
      the type specification of the iterator elements.
  r6   c                     || _         y r"   r   )r@   rz   s     r)   rF   zIteratorSpec.__init__  s
    %Dr+   c                     t         S r"   )r   ri   s    r)   
value_typezIteratorSpec.value_type  s    r+   c                     | j                   fS r"   r   ri   s    r)   
_serializezIteratorSpec._serialize  s      r+   c                 L    t        j                  g t        j                        fS r"   )r   
TensorSpecr   resourceri   s    r)   _component_specszIteratorSpec._component_specs  s    b&//244r+   c                     |j                   fS r"   )r2   )r@   r   s     r)   _to_componentszIteratorSpec._to_components  s    $$&&r+   c                 2    t        d || j                        S )N)r   r   rz   )r   r6   )r@   r   s     r)   _from_componentszIteratorSpec._from_components  s    '') )r+   c                 ,    t        | j                        S r"   r#  )r   s    r)   
from_valuezIteratorSpec.from_value  s    **++r+   N)r   r   r   r   	__slots__rF   r   r?  rA  rE  rG  rI  r   rK  r   r+   r)   r$  r$    sa    ( )&  ! 5 5') , ,r+   r$  c                   T     e Zd ZdZej
                  j                  f fd	Zd Z xZ	S )_IteratorSaveablez3SaveableObject for saving/restoring iterator state.c                     t        j                  ||j                        }t        j                  |d|dz   |j
                        g}t        t        | #  |||       y )N)r  rS   r   )device)	r   r   r   r   SaveSpecrP  r   rN  rF   )r@   rA   rx   r  r   specsr   s         r)   rF   z_IteratorSaveable.__init__  sg    
 *<<1F1L1LN 	!!8O$++		-E 

T+,=udKr+   c                     t        j                  | j                        5  t        j                  | j                  |d         cd d d        S # 1 sw Y   y xY w)Nr   )r   r   r   r   r   )r@   r   restored_shapess      r)   restorez_IteratorSaveable.restore  sG    			477	# P11$'';KA;NOP P Ps   #AA)
r   r   r   r   r   r   r   rF   rU  r:  r;  s   @r)   rN  rN    s#    ; (;;@@	L Pr+   rN  z6Use `tf.data.Iterator.get_next_as_optional()` instead.z&data.experimental.get_next_as_optionalc                 "    | j                         S )a|  Returns a `tf.experimental.Optional` with the next element of the iterator.

  If the iterator has reached the end of the sequence, the returned
  `tf.experimental.Optional` will have no value.

  Args:
    iterator: A `tf.data.Iterator`.

  Returns:
    A `tf.experimental.Optional` object which either contains the next element
    of the iterator (if it exists) or no value.
  )r   )iterators    r)   r   r     s      
	&	&	((r+   )Nr   r   	threadingr   tensorflow.core.protobufr    tensorflow.python.autograph.corer   r   tensorflow.python.checkpointr   tensorflow.python.data.opsr   r   r   r   tensorflow.python.data.utilr	   r
   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   r   r   r   r   r   tensorflow.python.opsr   r   r   r   tensorflow.python.ops.raggedr   tensorflow.python.saved_modelr   tensorflow.python.trackabler   	trackable tensorflow.python.training.saverr   tensorflow.python.utilr   tensorflow.python.util.compatr    tensorflow.python.util.tf_exportr   r   r   r  r  r?   r*   legacy_saveable_name	Trackabler/   r   Lockr   r   CompositeTensorABCMetar   r   TypeSpecr$  SaveableObjectrN  register_codecBuiltInTypeSpecCodecTypeSpecProtoDATA_ITERATOR_SPECr   r   register_overridesr   r+   r)   <module>ru     s(   % 
   / D 8 9 3 = , 1 + 8 . . + . 4 1 2 1 1 - , : @ 9 = . 9 6 #%   !# !     &%%j1
 A@y"" A@ ! 2A@H INN	$ ?r"`A$$kk	`A #`AF &%%j1IL I 2IX 2&0,9%% 0, '0,hP(77 P0 &  % %///j..AA 
BD
34) 5D)  &  % % 'r+   