
    AVh                       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 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/m0Z0 dd!l1m2Z2 dd"l3m4Z4 e'jj                  Z5 e2d#       G d$ d#ejl                  e.jn                  e.jp                               Z8d% Z9d& Z: e2d'       ejv                  d(       G d) d'ejx                  e.jz                                      Z= e)j|                   e)j~                  e=ej                  j                                ej                  e$j                  e=j                         	 	 	 dDd*ZEd+ ZFd, ZGd- ZHd. ZId/ ZJ ej                  e8eHeIeJ        G d0 d1      ZLd2 ZM ej                  d3      d4        ZOdEd5ZPdEd6ZQej                  fd7ZSd8 ZTd9 ZUd: ZVd; ZWd< ZXd= ZYd> ZZej                  e8fa\d? Z]d@ Z^dA Z_dB Z`ej                  e8e$j                  f   Zbej                  ebe,j                  f   ZdddCl"meZe y)Fz4Classes for storing ragged tensors and their values.    N)
struct_pb2)tf2)session)composite_tensor)composite_tensor_gradient)constant_op)dtypes)ops)sparse_tensor)tensor)tensor_conversion)tensor_shape)tensor_util)	type_spec)type_spec_registry)	array_ops)array_ops_stack)	check_ops)cond)control_flow_assert)gen_ragged_conversion_ops)math_ops)ragged_config)ragged_tensor_value)ragged_util)RowPartition)nested_structure_coder)coreinternal)dispatch)	tf_export)doc_controlsRaggedTensorc                   j   e Zd ZdZej
                  dWd       ZedXd       Zee	j                  	 	 	 dYd              Zee	j                  dZd              Zee	j                  dZd              Zee	j                  dZd              Zee	j                  dZd	              Zee	j                  	 	 	 d[d
              Zee	j                  	 	 	 dYd              Zee	j                  	 	 dZd              Zee	j                  	 	 dZd              Ze	 	 dZd       Zed        Zed        Zed        Zdej4                  fdZed        Zed        Zed        Zed        Zed        Z ed        Z!ed        Z"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$ Z+d% Z,d& Z-d' Z.d( Z/ee	j                  ddd de0jb                  fd)              Z2d_d*Z3ee	j                  de0jb                  fd+              Z4d\d,Z5ede0jb                  dfd-       Z6d`d.Z7d/ Z8d0 Z9d1 Z:d2 Z;d3 Z<d4 Z= e=d5      Z> e=d6      Z? e=d7      Z@ e=d8      ZA e=d9      ZB e=d:      ZC e=d;      ZD e=d<      ZE e=d=      ZF e=d>      ZG e=d?      ZH e=d@      ZI e=dA      ZJ e=dB      ZK e=dC      ZL e=dD      ZM e=dE      ZN e=dF      ZO e=dG      ZP e=dH      ZQ e=dI      ZR e=dJ      ZS e=dK      ZT e=dL      ZU e=dM      ZV e=dN      ZW e=dO      ZX e=dP      ZY e=dQ      ZZ e=dR      Z[[=dS Z\edT        Z]dU Z^dV Z_ e`j                         Zby)ar$   au   Represents a ragged tensor.

  A `RaggedTensor` is a tensor with one or more *ragged dimensions*, which are
  dimensions whose slices may have different lengths.  For example, the inner
  (column) dimension of `rt=[[3, 1, 4, 1], [], [5, 9, 2], [6], []]` is ragged,
  since the column slices (`rt[0, :]`, ..., `rt[4, :]`) have different lengths.
  Dimensions whose slices all have the same length are called *uniform
  dimensions*.  The outermost dimension of a `RaggedTensor` is always uniform,
  since it consists of a single slice (and so there is no possibility for
  differing slice lengths).

  The total number of dimensions in a `RaggedTensor` is called its *rank*,
  and the number of ragged dimensions in a `RaggedTensor` is called its
  *ragged-rank*.  A `RaggedTensor`'s ragged-rank is fixed at graph creation
  time: it can't depend on the runtime values of `Tensor`s, and can't vary
  dynamically for different session runs.

  Note that the `__init__` constructor is private. Please use one of the
  following methods to construct a `RaggedTensor`:

  * `tf.RaggedTensor.from_row_lengths`
  * `tf.RaggedTensor.from_value_rowids`
  * `tf.RaggedTensor.from_row_splits`
  * `tf.RaggedTensor.from_row_starts`
  * `tf.RaggedTensor.from_row_limits`
  * `tf.RaggedTensor.from_nested_row_splits`
  * `tf.RaggedTensor.from_nested_row_lengths`
  * `tf.RaggedTensor.from_nested_value_rowids`

  ### Potentially Ragged Tensors

  Many ops support both `Tensor`s and `RaggedTensor`s
  (see [tf.ragged](https://www.tensorflow.org/api_docs/python/tf/ragged) for a
  full listing). The term "potentially ragged tensor" may be used to refer to a
  tensor that might be either a `Tensor` or a `RaggedTensor`.  The ragged-rank
  of a `Tensor` is zero.

  ### Documenting RaggedTensor Shapes

  When documenting the shape of a RaggedTensor, ragged dimensions can be
  indicated by enclosing them in parentheses.  For example, the shape of
  a 3-D `RaggedTensor` that stores the fixed-size word embedding for each
  word in a sentence, for each sentence in a batch, could be written as
  `[num_sentences, (num_words), embedding_size]`.  The parentheses around
  `(num_words)` indicate that dimension is ragged, and that the length
  of each element list in that dimension may vary for each item.

  ### Component Tensors

  Internally, a `RaggedTensor` consists of a concatenated list of values that
  are partitioned into variable-length rows.  In particular, each `RaggedTensor`
  consists of:

    * A `values` tensor, which concatenates the variable-length rows into a
      flattened list.  For example, the `values` tensor for
      `[[3, 1, 4, 1], [], [5, 9, 2], [6], []]` is `[3, 1, 4, 1, 5, 9, 2, 6]`.

    * A `row_splits` vector, which indicates how those flattened values are
      divided into rows.  In particular, the values for row `rt[i]` are stored
      in the slice `rt.values[rt.row_splits[i]:rt.row_splits[i+1]]`.

  Example:

  >>> print(tf.RaggedTensor.from_row_splits(
  ...       values=[3, 1, 4, 1, 5, 9, 2, 6],
  ...       row_splits=[0, 4, 4, 7, 8, 8]))
  <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>

  ### Alternative Row-Partitioning Schemes

  In addition to `row_splits`, ragged tensors provide support for five other
  row-partitioning schemes:

    * `row_lengths`: a vector with shape `[nrows]`, which specifies the length
      of each row.

    * `value_rowids` and `nrows`: `value_rowids` is a vector with shape
      `[nvals]`, corresponding one-to-one with `values`, which specifies
      each value's row index.  In particular, the row `rt[row]` consists of the
      values `rt.values[j]` where `value_rowids[j]==row`.  `nrows` is an
      integer scalar that specifies the number of rows in the
      `RaggedTensor`. (`nrows` is used to indicate trailing empty rows.)

    * `row_starts`: a vector with shape `[nrows]`, which specifies the start
      offset of each row.  Equivalent to `row_splits[:-1]`.

    * `row_limits`: a vector with shape `[nrows]`, which specifies the stop
      offset of each row.  Equivalent to `row_splits[1:]`.

    * `uniform_row_length`: A scalar tensor, specifying the length of every
      row.  This row-partitioning scheme may only be used if all rows have
      the same length.

  Example: The following ragged tensors are equivalent, and all represent the
  nested list `[[3, 1, 4, 1], [], [5, 9, 2], [6], []]`.

  >>> values = [3, 1, 4, 1, 5, 9, 2, 6]
  >>> RaggedTensor.from_row_splits(values, row_splits=[0, 4, 4, 7, 8, 8])
  <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>
  >>> RaggedTensor.from_row_lengths(values, row_lengths=[4, 0, 3, 1, 0])
  <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>
  >>> RaggedTensor.from_value_rowids(
  ...     values, value_rowids=[0, 0, 0, 0, 2, 2, 2, 3], nrows=5)
  <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>
  >>> RaggedTensor.from_row_starts(values, row_starts=[0, 4, 4, 7, 8])
  <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>
  >>> RaggedTensor.from_row_limits(values, row_limits=[4, 4, 7, 8, 8])
  <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>
  >>> RaggedTensor.from_uniform_row_length(values, uniform_row_length=2)
  <tf.RaggedTensor [[3, 1], [4, 1], [5, 9], [2, 6]]>

  ### Multiple Ragged Dimensions

  `RaggedTensor`s with multiple ragged dimensions can be defined by using
  a nested `RaggedTensor` for the `values` tensor.  Each nested `RaggedTensor`
  adds a single ragged dimension.

  >>> inner_rt = RaggedTensor.from_row_splits(  # =rt1 from above
  ...     values=[3, 1, 4, 1, 5, 9, 2, 6], row_splits=[0, 4, 4, 7, 8, 8])
  >>> outer_rt = RaggedTensor.from_row_splits(
  ...     values=inner_rt, row_splits=[0, 3, 3, 5])
  >>> print(outer_rt.to_list())
  [[[3, 1, 4, 1], [], [5, 9, 2]], [], [[6], []]]
  >>> print(outer_rt.ragged_rank)
  2

  The factory function `RaggedTensor.from_nested_row_splits` may be used to
  construct a `RaggedTensor` with multiple ragged dimensions directly, by
  providing a list of `row_splits` tensors:

  >>> RaggedTensor.from_nested_row_splits(
  ...     flat_values=[3, 1, 4, 1, 5, 9, 2, 6],
  ...     nested_row_splits=([0, 3, 3, 5], [0, 4, 4, 7, 8, 8])).to_list()
  [[[3, 1, 4, 1], [], [5, 9, 2]], [], [[6], []]]

  ### Uniform Inner Dimensions

  `RaggedTensor`s with uniform inner dimensions can be defined
  by using a multidimensional `Tensor` for `values`.

  >>> rt = RaggedTensor.from_row_splits(values=tf.ones([5, 3], tf.int32),
  ...                                   row_splits=[0, 2, 5])
  >>> print(rt.to_list())
  [[[1, 1, 1], [1, 1, 1]],
   [[1, 1, 1], [1, 1, 1], [1, 1, 1]]]
  >>> print(rt.shape)
  (2, None, 3)

  ### Uniform Outer Dimensions

  `RaggedTensor`s with uniform outer dimensions can be defined by using
  one or more `RaggedTensor` with a `uniform_row_length` row-partitioning
  tensor.  For example, a `RaggedTensor` with shape `[2, 2, None]` can be
  constructed with this method from a `RaggedTensor` values with shape
  `[4, None]`:

  >>> values = tf.ragged.constant([[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]])
  >>> print(values.shape)
  (4, None)
  >>> rt6 = tf.RaggedTensor.from_uniform_row_length(values, 2)
  >>> print(rt6)
  <tf.RaggedTensor [[[1, 2, 3], [4]], [[5, 6], [7, 8, 9, 10]]]>
  >>> print(rt6.shape)
  (2, 2, None)

  Note that `rt6` only contains one ragged dimension (the innermost
  dimension). In contrast, if `from_row_splits` is used to construct a similar
  `RaggedTensor`, then that `RaggedTensor` will have two ragged dimensions:

  >>> rt7 = tf.RaggedTensor.from_row_splits(values, [0, 2, 4])
  >>> print(rt7.shape)
  (2, None, None)

  Uniform and ragged outer dimensions may be interleaved, meaning that a
  tensor with any combination of ragged and uniform dimensions may be created.
  For example, a RaggedTensor `t4` with shape `[3, None, 4, 8, None, 2]` could
  be constructed as follows:

  ```python
  t0 = tf.zeros([1000, 2])                           # Shape:         [1000, 2]
  t1 = RaggedTensor.from_row_lengths(t0, [...])      #           [160, None, 2]
  t2 = RaggedTensor.from_uniform_row_length(t1, 8)   #         [20, 8, None, 2]
  t3 = RaggedTensor.from_uniform_row_length(t2, 4)   #       [5, 4, 8, None, 2]
  t4 = RaggedTensor.from_row_lengths(t3, [...])      # [3, None, 4, 8, None, 2]
  ```

  c                 .   |st        d      t        |       t        |t              st	        d| d      |j
                  j                  d       t        |t              r%|j                  |j                  j                  k(  sJ || _
        || _	        y)ai  Creates a `RaggedTensor` with a specified partitioning for `values`.

    This constructor is private -- please use one of the following ops to
    build `RaggedTensor`s:

      * `tf.RaggedTensor.from_row_lengths`
      * `tf.RaggedTensor.from_value_rowids`
      * `tf.RaggedTensor.from_row_splits`
      * `tf.RaggedTensor.from_row_starts`
      * `tf.RaggedTensor.from_row_limits`
      * `tf.RaggedTensor.from_nested_row_splits`
      * `tf.RaggedTensor.from_nested_row_lengths`
      * `tf.RaggedTensor.from_nested_value_rowids`

    Args:
      values: A potentially ragged tensor of any dtype and shape `[nvals, ...]`.
      row_partition: A `RowPartition` object, representing the arrangement of
        the lists at the top level.
      internal: True if the constructor is being called by one of the factory
        methods.  If false, an exception will be raised.

    Raises:
      ValueError: If internal = False. Note that this method is intended only
                 for internal use.
      TypeError: If values is not a `RaggedTensor` or `Tensor`, or
                 row_partition is not a `RowPartition`.
    zzRaggedTensor constructor is private; please use one of the factory methods instead (e.g., RaggedTensor.from_row_lengths()):Argument `row_partition` must be a RowPartition. Received .   N)
ValueError'_assert_is_supported_ragged_values_type
isinstancer   	TypeErrorshapewith_rank_at_leastr$   dtype_row_partition_values)selfvaluesrow_partitionr    s       Z/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/ragged/ragged_tensor.py__init__zRaggedTensor.__init__  s    <  : ; ; ,F3m\2 ""/3 4 4 LL##A&&,'  F$9$9$?$????DL'D    c                    t        |t              st        d| d      t        |t              st        d| d      | j	                  ||d      \  }}|j                         r8|j                         j                  }|j                  dd j                  |       |rd}t        ||j                        }t        j                  t        j                  |j                         |j                        ||      g}t        |t               s%|j#                  t        j$                  |d             |j'                  |      } | |d	|
      S )ao  Creates a `RaggedTensor` with a row partition.

    This is used as a way for RaggedTensors to share row partitions.

    The outer dimension of values must be equal to `partition.nvals()`.

    Args:
      values: A potentially ragged tensor.
      row_partition: a `RowPartition`: can be shared between tensors.
      validate: If true, then use assertions to check that the arguments form a
        valid `RaggedTensor`.

    Returns:
      A `RaggedTensor`.  `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.

    Raises:
      ValueError: If partition.nvals() != _nrows(values)
    r'   r(   2Argument `validate` must have type bool. Received 	partitionNr)   zAArguments to _from_row_partition do not form a valid RaggedTensormessageT)r4   r    r5   )r,   r   r-   bool_convert_values_and_partition_has_precomputed_value_rowidsvalue_rowidsr.   assert_is_compatible_with_nrowsr0   r   assert_equalr   castnvalsr$   appendassert_rank_at_least_with_dependencies)clsr4   r5   validatevalue_rowids_shapemsgrF   checkss           r6   _from_row_partitionz RaggedTensor._from_row_partition:  sA   * m\2 ""/3 4 4h% ""*1. / /=={,FM224(557==ll2A001CDOcV]001e

 
 mmM//1=3F3FGf -i44VQ?@#66v>mft=IIr8   Nc           	         t        |t              st        d| d      t        j                  |d|||g      5  t        j                  |||t        |            }| j                  |||      cddd       S # 1 sw Y   yxY w)ai  Creates a `RaggedTensor` with rows partitioned by `value_rowids`.

    The returned `RaggedTensor` corresponds with the python list defined by:

    ```python
    result = [[values[i] for i in range(len(values)) if value_rowids[i] == row]
              for row in range(nrows)]
    ```

    Args:
      values: A potentially ragged tensor with shape `[nvals, ...]`.
      value_rowids: A 1-D integer tensor with shape `[nvals]`, which corresponds
        one-to-one with `values`, and specifies each value's row index.  Must be
        nonnegative, and must be sorted in ascending order.
      nrows: An integer scalar specifying the number of rows.  This should be
        specified if the `RaggedTensor` may containing empty training rows. Must
        be greater than `value_rowids[-1]` (or zero if `value_rowids` is empty).
        Defaults to `value_rowids[-1] + 1` (or zero if `value_rowids` is empty).
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor`.  `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.

    Raises:
      ValueError: If `nrows` is incompatible with `value_rowids`.

    #### Example:

    >>> print(tf.RaggedTensor.from_value_rowids(
    ...     values=[3, 1, 4, 1, 5, 9, 2, 6],
    ...     value_rowids=[0, 0, 0, 0, 2, 2, 2, 3],
    ...     nrows=5))
    <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>

    r:   r(   RaggedFromValueRowIds)rA   nrowsrK   
dtype_hintrK   N)	r,   r>   r-   r
   
name_scoper   from_value_rowids_get_optional_partition_dtyperO   )rJ   r4   rA   rR   namerK   r5   s          r6   rV   zRaggedTensor.from_value_rowidsh  s    ^ h% ""*1. / / 
5u5
7 O"44#26:	<m
 $$V]X$NO O Os   6A::Bc                    t        |t              st        d| d      t        j                  |d||g      5  t        j                  ||t        |            }| j                  |||      cddd       S # 1 sw Y   yxY w)a  Creates a `RaggedTensor` with rows partitioned by `row_splits`.

    The returned `RaggedTensor` corresponds with the python list defined by:

    ```python
    result = [values[row_splits[i]:row_splits[i + 1]]
              for i in range(len(row_splits) - 1)]
    ```

    Args:
      values: A potentially ragged tensor with shape `[nvals, ...]`.
      row_splits: A 1-D integer tensor with shape `[nrows+1]`.  Must not be
        empty, and must be sorted in ascending order.  `row_splits[0]` must be
        zero and `row_splits[-1]` must be `nvals`.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor`.  `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.

    Raises:
      ValueError: If `row_splits` is an empty list.

    #### Example:

    >>> print(tf.RaggedTensor.from_row_splits(
    ...     values=[3, 1, 4, 1, 5, 9, 2, 6],
    ...     row_splits=[0, 4, 4, 7, 8, 8]))
    <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>

    r:   r(   RaggedFromRowSplits)
row_splitsrK   rS   rT   N)	r,   r>   r-   r
   rU   r   from_row_splitsrW   rO   )rJ   r4   r[   rX   rK   r5   s         r6   r\   zRaggedTensor.from_row_splits  s    J h% ""*1. / / 
3fj5I	J O"2226:<m $$V]X$NO O O   5A88Bc                    t        |t              st        d| d      t        j                  |d||g      5  t        j                  ||t        |            }| j                  |||      cddd       S # 1 sw Y   yxY w)aB  Creates a `RaggedTensor` with rows partitioned by `row_lengths`.

    The returned `RaggedTensor` corresponds with the python list defined by:

    ```python
    result = [[values.pop(0) for i in range(length)]
              for length in row_lengths]
    ```

    Args:
      values: A potentially ragged tensor with shape `[nvals, ...]`.
      row_lengths: A 1-D integer tensor with shape `[nrows]`.  Must be
        nonnegative.  `sum(row_lengths)` must be `nvals`.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor`.  `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.

    #### Example:

    >>> print(tf.RaggedTensor.from_row_lengths(
    ...     values=[3, 1, 4, 1, 5, 9, 2, 6],
    ...     row_lengths=[4, 0, 3, 1, 0]))
    <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>

    r:   r(   RaggedFromRowLengths)row_lengthsrK   rS   rT   N)	r,   r>   r-   r
   rU   r   from_row_lengthsrW   rO   )rJ   r4   r`   rX   rK   r5   s         r6   ra   zRaggedTensor.from_row_lengths  s    B h% ""*1. / / 
4v{6K	L O"33!26:<m $$V]X$NO O Or]   c           	      2   t        |t              st        d| d      t        j                  |d||g      5  t        |      }t        j                  |t        |      |t        |            }| j                  |||      cddd       S # 1 sw Y   yxY w)a  Creates a `RaggedTensor` with rows partitioned by `row_starts`.

    Equivalent to: `from_row_splits(values, concat([row_starts, nvals]))`.

    Args:
      values: A potentially ragged tensor with shape `[nvals, ...]`.
      row_starts: A 1-D integer tensor with shape `[nrows]`.  Must be
        nonnegative and sorted in ascending order.  If `nrows>0`, then
        `row_starts[0]` must be zero.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor`.  `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.

    #### Example:

    >>> print(tf.RaggedTensor.from_row_starts(
    ...     values=[3, 1, 4, 1, 5, 9, 2, 6],
    ...     row_starts=[0, 4, 4, 7, 8]))
    <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>

    r:   r(   RaggedFromRowStarts)
row_startsrF   rK   rS   rT   N)r,   r>   r-   r
   rU    _convert_to_ragged_tensor_valuesr   from_row_startsrC   rW   rO   )rJ   r4   rd   rX   rK   r5   s         r6   rf   zRaggedTensor.from_row_starts   s    : h% ""*1. / /	3fj5I	J O/7f"22v26:	<m
 $$V]X$NO O Os   A
BBc                    t        |t              st        d| d      t        j                  |d||g      5  t        |      }t        j                  ||t        |            }| j                  |||      cddd       S # 1 sw Y   yxY w)a  Creates a `RaggedTensor` with rows partitioned by `row_limits`.

    Equivalent to: `from_row_splits(values, concat([0, row_limits]))`.

    Args:
      values: A potentially ragged tensor with shape `[nvals, ...]`.
      row_limits: A 1-D integer tensor with shape `[nrows]`.  Must be sorted in
        ascending order.  If `nrows>0`, then `row_limits[-1]` must be `nvals`.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor`.  `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.

    #### Example:

    >>> print(tf.RaggedTensor.from_row_limits(
    ...     values=[3, 1, 4, 1, 5, 9, 2, 6],
    ...     row_limits=[4, 4, 7, 8, 8]))
    <tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], []]>

    r:   r(   RaggedFromRowLimits)
row_limitsrK   rS   rT   N)
r,   r>   r-   r
   rU   re   r   from_row_limitsrW   rO   )rJ   r4   ri   rX   rK   r5   s         r6   rj   zRaggedTensor.from_row_limits)  s    8 h% ""*1. / /	3fj5I	J O/7f"2226:<m $$V]X$NO O Os   A BBc           
      h   t        |t              st        d| d      t        j                  |d|||g      5  t        |      }t        |dt        |            }t        ||      }t        j                  ||||t        |            }| j                  |||      cddd       S # 1 sw Y   yxY w)ad  Creates a `RaggedTensor` with rows partitioned by `uniform_row_length`.

    This method can be used to create `RaggedTensor`s with multiple uniform
    outer dimensions.  For example, a `RaggedTensor` with shape `[2, 2, None]`
    can be constructed with this method from a `RaggedTensor` values with shape
    `[4, None]`:

    >>> values = tf.ragged.constant([[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]])
    >>> print(values.shape)
    (4, None)
    >>> rt1 = tf.RaggedTensor.from_uniform_row_length(values, 2)
    >>> print(rt1)
    <tf.RaggedTensor [[[1, 2, 3], [4]], [[5, 6], [7, 8, 9, 10]]]>
    >>> print(rt1.shape)
    (2, 2, None)

    Note that `rt1` only contains one ragged dimension (the innermost
    dimension). In contrast, if `from_row_splits` is used to construct a similar
    `RaggedTensor`, then that `RaggedTensor` will have two ragged dimensions:

    >>> rt2 = tf.RaggedTensor.from_row_splits(values, [0, 2, 4])
    >>> print(rt2.shape)
    (2, None, None)

    Args:
      values: A potentially ragged tensor with shape `[nvals, ...]`.
      uniform_row_length: A scalar integer tensor.  Must be nonnegative. The
        size of the outer axis of `values` must be evenly divisible by
        `uniform_row_length`.
      nrows: The number of rows in the constructed RaggedTensor.  If not
        specified, then it defaults to `nvals/uniform_row_length` (or `0` if
        `uniform_row_length==0`).  `nrows` only needs to be specified if
        `uniform_row_length` might be zero.  `uniform_row_length*nrows` must be
        `nvals`.
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.
      name: A name prefix for the RaggedTensor (optional).

    Returns:
      A `RaggedTensor` that corresponds with the python list defined by:

      ```python
      result = [[values.pop(0) for i in range(uniform_row_length)]
                for _ in range(nrows)]
      ```

      `result.rank = values.rank + 1`.
      `result.ragged_rank = values.ragged_rank + 1`.
    r:   r(   RaggedFromUniformRowLengthUniformRowLength)uniform_row_lengthrF   rR   rK   rS   rT   N)r,   r>   r-   r
   rU   re   _convert_row_partitionrW   _nvals_uniform_row_lengthr   from_uniform_row_lengthrO   )rJ   r4   rn   rR   rK   rX   rF   r5   s           r6   rq   z$RaggedTensor.from_uniform_row_lengthP  s    t h% ""*1. / /	:!3U;
= O/7f1
0
'
/1 (0BCe"::/26:<m $$V]X$NO O Os   A$B((B1c           	         t        |t              st        d| d      t        |t        j                        rt        d| d      |dgt        |      z  }ndt        |t        j                        rt        d| d      t        |      t        |      k7  r$t        dt        |       dt        |       d      t        j                  |d|gt        |      z   t        |      z         5  |}t        t        t        ||                  D ]  \  }}| j                  ||||	      } |cddd       S # 1 sw Y   yxY w)
a#  Creates a `RaggedTensor` from a nested list of `value_rowids` tensors.

    Equivalent to:

    ```python
    result = flat_values
    for (rowids, nrows) in reversed(zip(nested_value_rowids, nested_nrows)):
      result = from_value_rowids(result, rowids, nrows)
    ```

    Args:
      flat_values: A potentially ragged tensor.
      nested_value_rowids: A list of 1-D integer tensors.  The `i`th tensor is
        used as the `value_rowids` for the `i`th ragged dimension.
      nested_nrows: A list of integer scalars.  The `i`th scalar is used as the
        `nrows` for the `i`th ragged dimension.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor` (or `flat_values` if `nested_value_rowids` is empty).

    Raises:
      ValueError: If `len(nested_values_rowids) != len(nested_nrows)`.
    r:   r(   zCArgument `nested_value_rowids` must be a list of Tensors. Received Nz<Argument `nested_nrows` must be a list of Tensors. Received ziArgument `nested_nrows` must have the same length as argument `nested_value_rowids`. len(nested_nrows) = z! vs. len(nested_values_rowids) = RaggedFromNestedValueRowIdsrT   )r,   r>   r-   
tensor_libTensorlenr*   r
   rU   listreversedziprV   )	rJ   flat_valuesnested_value_rowidsnested_nrowsrX   rK   resultrA   rR   s	            r6   from_nested_value_rowidsz%RaggedTensor.from_nested_value_rowids  s   F h% ""*1. / /%z'8'89 ++>*?qB C CVc"566l	L*"3"3	4 --9N!= > 	>	\	c"56	6C< !!B&'(+, 	, 
;k]01>2484F>G 
H f!)
s&5
6"8 <
,&&L%( ' <<   s   /?D88Ec                 V   t        |t              st        d| d      t        |t        j                        rt        d| d      t        j                  |d|gt        |      z         5  |}t        |      D ]  }| j                  |||      } |cddd       S # 1 sw Y   yxY w)a(  Creates a `RaggedTensor` from a nested list of `row_splits` tensors.

    Equivalent to:

    ```python
    result = flat_values
    for row_splits in reversed(nested_row_splits):
      result = from_row_splits(result, row_splits)
    ```

    Args:
      flat_values: A potentially ragged tensor.
      nested_row_splits: A list of 1-D integer tensors.  The `i`th tensor is
        used as the `row_splits` for the `i`th ragged dimension.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor` (or `flat_values` if `nested_row_splits` is empty).
    r:   r(   zAArgument `nested_row_splits` must be a list of Tensors. Received RaggedFromNestedRowSplitsrT   N)
r,   r>   r-   rt   ru   r
   rU   rw   rx   r\   )rJ   rz   nested_row_splitsrX   rK   r}   splitss          r6   from_nested_row_splitsz#RaggedTensor.from_nested_row_splits  s    : h% ""*1. / /#Z%6%67 ++<*=Q@ A A	9$->(??
A f./ H&$$VVh$GH     -(BB(c                 V   t        |t              st        d| d      t        |t        j                        rt        d| d      t        j                  |d|gt        |      z         5  |}t        |      D ]  }| j                  |||      } |cddd       S # 1 sw Y   yxY w)a0  Creates a `RaggedTensor` from a nested list of `row_lengths` tensors.

    Equivalent to:

    ```python
    result = flat_values
    for row_lengths in reversed(nested_row_lengths):
      result = from_row_lengths(result, row_lengths)
    ```

    Args:
      flat_values: A potentially ragged tensor.
      nested_row_lengths: A list of 1-D integer tensors.  The `i`th tensor is
        used as the `row_lengths` for the `i`th ragged dimension.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor` (or `flat_values` if `nested_row_lengths` is empty).
    r:   r(   zBArgument `nested_row_lengths` must be a list of Tensors. Received RaggedFromNestedRowlengthsrT   N)
r,   r>   r-   rt   ru   r
   rU   rw   rx   ra   )rJ   rz   nested_row_lengthsrX   rK   r}   lengthss          r6   from_nested_row_lengthsz$RaggedTensor.from_nested_row_lengths  s    : h% ""*1. / /$j&7&78 ++=*>aA B B	:$-?(@@
B f01 J'%%fg%IJ  r   c                    t        |t              st        d| d      t        |t              rt        d| d      t        |t        j
                        rt        d| d      t        j                  |d|gt        |      z         5  |}t        |      D ]  }| j                  |||      } |cddd       S # 1 sw Y   yxY w)a2  Creates a `RaggedTensor` from a nested list of row partitions.

    Equivalent to:

    ```python
    result = flat_values
    for row_partition in reversed(nested_row_partitions):
      result = _from_row_partition(result, row_partition)
    ```

    Args:
      flat_values: A potentially ragged tensor.
      nested_row_partitions: A list of row partitions.  The `i`th element is
        used as the row partition for the `i`th ragged dimension.
      name: A name prefix for the RaggedTensor (optional).
      validate: If true, then use assertions to check that the arguments form
        a valid `RaggedTensor`.  Note: these assertions incur a runtime cost,
          since they must be checked for each tensor value.

    Returns:
      A `RaggedTensor` (or `flat_values` if `nested_row_lengths` is empty).
    r:   r(   zKArgument `nested_row_partitions` must be a list of RowPartitions. Received RaggedFromNestedRowPartitionsrT   N)r,   r>   r-   r   rt   ru   r
   rU   rw   rx   rO   )rJ   rz   nested_row_partitionsrX   rK   r}   r;   s          r6   _from_nested_row_partitionsz(RaggedTensor._from_nested_row_partitions/  s    8 h% ""*1. / /'6 11F0GqJ K K'):):; 11F0GqJ K K	=$-B(CC
E f 56 O)((X(NO  s   (B>>Cc           	         t        |t              st        d| d      t        |t              r|j                  j
                  |j
                  k7  rbt        j                         s3t        d| d|j
                   d|j                  j
                   d      |j                  |j
                        }||fS t        |      }||fS )a  Converts `values` and `partition` to Tensors.

    If `values` is a `RaggedTensor`, then converts `values` and `partition`
    to have compatible row-partitioning dtypes.  In particular, if any of the
    row partitioning tensors are `int64`, then all of the other row
    partitioning tensors wil be cast to `int64` (if auto_cast_partition_dtype()
    is true) or an error will be raised (if auto_cast_partition_dtype() is
    false).

    Args:
      values: The `values` for the `RaggedTensor` being constructed.
      row_partition: A RowPartition object for the `RaggedTensor` being
        constructed.
      name: The name of the RowPartition object.

    Returns:
      A tuple (values, partition).
    r'   r(   z4Argument `row_partition` of RaggedTensor with name: z- must have same dtype as Argument `values`. ( vs. ).)r,   r   r-   r$   r1   r0   r   auto_cast_partition_dtyper*   with_row_splits_dtypere   )rJ   r4   r5   rX   s       r6   r?   z*RaggedTensor._convert_values_and_partition[  s    ( m\2 ""/3 4 4&,'				$	$(;(;	;668 DTF K%%&eF,A,A,G,G+HLM M --m.A.AB M"" 07fM""r8   c                 .    | j                   j                  S )z%The `DType` of values in this tensor.)r2   r0   r3   s    r6   r0   zRaggedTensor.dtype  s     <<r8   c                     | j                   j                  }| j                   j                  }| j                  j                  dd }t        j                  ||g      j                  |      S )a  The statically known shape of this ragged tensor.

    Returns:
      A `TensorShape` containing the statically known shape of this ragged
      tensor.  Ragged dimensions have a size of `None`.

    Examples:

    >>> tf.ragged.constant([[0], [1, 2]]).shape
    TensorShape([2, None])

    >>> tf.ragged.constant([[[0, 1]], [[1, 2], [3, 4]]], ragged_rank=1).shape
    TensorShape([2, None, 2])

    r)   N)r1   static_nrowsstatic_uniform_row_lengthr2   r.   r   TensorShapeconcatenate)r3   rR   ncolsvalue_shapes       r6   r.   zRaggedTensor.shape  s\    " ,,E99E,,$$QR(K##UEN3??LLr8   returnc                     | j                   S )a  The statically known shape of this ragged tensor.

    Returns:
      A `TensorShape` containing the statically known shape of this ragged
      tensor.  Ragged dimensions have a size of `None`.

    Alias for `shape` property.

    Examples:

    >>> tf.ragged.constant([[0], [1, 2]]).get_shape()
    TensorShape([2, None])

    >>> tf.ragged.constant(
    ...    [[[0, 1]], [[1, 2], [3, 4]]], ragged_rank=1).get_shape()
    TensorShape([2, None, 2])

    )r.   r   s    r6   	get_shapezRaggedTensor.get_shape  s    & ::r8   c                 p    t        | j                  t              }|r| j                  j                  dz   S dS )a  The number of times the RaggedTensor's flat_values is partitioned.

    Examples:

    >>> values = tf.ragged.constant([[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]])
    >>> values.ragged_rank
    1

    >>> rt = tf.RaggedTensor.from_uniform_row_length(values, 2)
    >>> rt.ragged_rank
    2

    Returns:
      A Python `int` indicating the number of times the underlying `flat_values`
      Tensor has been partitioned to add a new dimension.
      I.e., `tf.rank(rt) = tf.rank(rt.flat_values) + rt.ragged_rank`.
    r)   )r,   r2   r$   ragged_rank)r3   values_is_raggeds     r6   r   zRaggedTensor.ragged_rank  s1    & "$,,=+;4<<##a'BBr8   c                     | j                   S )aG  The concatenated rows for this ragged tensor.

    `rt.values` is a potentially ragged tensor formed by flattening the two
    outermost dimensions of `rt` into a single dimension.

    `rt.values.shape = [nvals] + rt.shape[2:]` (where `nvals` is the
    number of items in the outer two dimensions of `rt`).

    `rt.ragged_rank = self.ragged_rank - 1`

    Returns:
      A potentially ragged tensor.

    #### Example:

    >>> rt = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    >>> print(rt.values)
    tf.Tensor([3 1 4 1 5 9 2 6], shape=(8,), dtype=int32)

    )r2   r   s    r6   r4   zRaggedTensor.values  s    , <<r8   c                     | j                   g}| j                  }t        |t              r8|j	                  |j                          |j                  }t        |t              r8t        |      S )z3Returns the row partitions for this `RaggedTensor`.)r1   r4   r,   r$   rG   tuple)r3   
partitions	rt_valuess      r6   _nested_row_partitionsz#RaggedTensor._nested_row_partitions  s]     %%&JI
Y
-	001""i Y
- r8   c                 6    | j                   j                         S )a  The row-split indices for this ragged tensor's `values`.

    `rt.row_splits` specifies where the values for each row begin and end in
    `rt.values`.  In particular, the values for row `rt[i]` are stored in
    the slice `rt.values[rt.row_splits[i]:rt.row_splits[i+1]]`.

    Returns:
      A 1-D integer `Tensor` with shape `[self.nrows+1]`.
      The returned tensor is non-empty, and is sorted in ascending order.
      `self.row_splits[0]` is zero, and `self.row_splits[-1]` is equal to
      `self.values.shape[0]`.

    #### Example:

    >>> rt = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    >>> print(rt.row_splits)  # indices of row splits in rt.values
    tf.Tensor([0 4 4 7 8 8], shape=(6,), dtype=int64)

    )r1   r[   r   s    r6   r[   zRaggedTensor.row_splits  s    * ))++r8   c                 6    | j                   j                         S )a  The length of each row in this ragged tensor, or None if rows are ragged.

    >>> rt1 = tf.ragged.constant([[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]])
    >>> print(rt1.uniform_row_length)  # rows are ragged.
    None

    >>> rt2 = tf.RaggedTensor.from_uniform_row_length(
    ...     values=rt1, uniform_row_length=2)
    >>> print(rt2)
    <tf.RaggedTensor [[[1, 2, 3], [4]], [[5, 6], [7, 8, 9, 10]]]>
    >>> print(rt2.uniform_row_length)  # rows are not ragged (all have size 2).
    tf.Tensor(2, shape=(), dtype=int64)

    A RaggedTensor's rows are only considered to be uniform (i.e. non-ragged)
    if it can be determined statically (at graph construction time) that the
    rows all have the same length.

    Returns:
      A scalar integer `Tensor`, specifying the length of every row in this
      ragged tensor (for ragged tensors whose rows are uniform); or `None`
      (for ragged tensors whose rows are ragged).
    )r1   rn   r   s    r6   rn   zRaggedTensor.uniform_row_length  s    0 1133r8   c                 x    | j                   }t        |t              r|j                   }t        |t              r|S )a  The innermost `values` tensor for this ragged tensor.

    Concretely, if `rt.values` is a `Tensor`, then `rt.flat_values` is
    `rt.values`; otherwise, `rt.flat_values` is `rt.values.flat_values`.

    Conceptually, `flat_values` is the tensor formed by flattening the
    outermost dimension and all of the ragged dimensions into a single
    dimension.

    `rt.flat_values.shape = [nvals] + rt.shape[rt.ragged_rank + 1:]`
    (where `nvals` is the number of items in the flattened dimensions).

    Returns:
      A `Tensor`.

    #### Example:

    >>> rt = tf.ragged.constant([[[3, 1, 4, 1], [], [5, 9, 2]], [], [[6], []]])
    >>> print(rt.flat_values)
    tf.Tensor([3 1 4 1 5 9 2 6], shape=(8,), dtype=int32)

    r4   r,   r$   )r3   r   s     r6   rz   zRaggedTensor.flat_values   s4    0 I
Y
-""i Y
-r8   c                     | j                   g}| j                  }t        |t              r8|j	                  |j                          |j                  }t        |t              r8t        |      S )aJ  A tuple containing the row_splits for all ragged dimensions.

    `rt.nested_row_splits` is a tuple containing the `row_splits` tensors for
    all ragged dimensions in `rt`, ordered from outermost to innermost.  In
    particular, `rt.nested_row_splits = (rt.row_splits,) + value_splits` where:

        * `value_splits = ()` if `rt.values` is a `Tensor`.
        * `value_splits = rt.values.nested_row_splits` otherwise.

    Returns:
      A `tuple` of 1-D integer `Tensor`s.

    #### Example:

    >>> rt = tf.ragged.constant(
    ...     [[[[3, 1, 4, 1], [], [5, 9, 2]], [], [[6], []]]])
    >>> for i, splits in enumerate(rt.nested_row_splits):
    ...   print('Splits for dimension %d: %s' % (i+1, splits.numpy()))
    Splits for dimension 1: [0 3]
    Splits for dimension 2: [0 3 3 5]
    Splits for dimension 3: [0 4 4 7 8 8]

    )r[   r4   r,   r$   rG   r   )r3   rt_nested_splitsr   s      r6   r   zRaggedTensor.nested_row_splits=  s]    2 (I
Y
-i223""i Y
- !""r8   c                     t        j                  |d| g      5  | j                  j                         cddd       S # 1 sw Y   yxY w)aX  Returns the row indices for the `values` in this ragged tensor.

    `rt.value_rowids()` corresponds one-to-one with the outermost dimension of
    `rt.values`, and specifies the row containing each value.  In particular,
    the row `rt[row]` consists of the values `rt.values[j]` where
    `rt.value_rowids()[j] == row`.

    Args:
      name: A name prefix for the returned tensor (optional).

    Returns:
      A 1-D integer `Tensor` with shape `self.values.shape[:1]`.
      The returned tensor is nonnegative, and is sorted in ascending order.

    #### Example:

    >>> rt = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    >>> print(rt.values)
    tf.Tensor([3 1 4 1 5 9 2 6], shape=(8,), dtype=int32)
    >>> print(rt.value_rowids())  # corresponds 1:1 with rt.values
    tf.Tensor([0 0 0 0 2 2 2 3], shape=(8,), dtype=int64)

    RaggedValueRowIdsN)r
   rU   r1   rA   r3   rX   s     r6   rA   zRaggedTensor.value_rowids]  s>    0 
1D6	: 0  --/0 0 0	   =Ac                 F   t        j                  |d| g      5  | j                         g}| j                  }t	        |t
              r<|j                  |j                                |j                  }t	        |t
              r<t        |      cddd       S # 1 sw Y   yxY w)a  Returns a tuple containing the value_rowids for all ragged dimensions.

    `rt.nested_value_rowids` is a tuple containing the `value_rowids` tensors
    for
    all ragged dimensions in `rt`, ordered from outermost to innermost.  In
    particular, `rt.nested_value_rowids = (rt.value_rowids(),) + value_ids`
    where:

    * `value_ids = ()` if `rt.values` is a `Tensor`.
    * `value_ids = rt.values.nested_value_rowids` otherwise.

    Args:
      name: A name prefix for the returned tensors (optional).

    Returns:
      A `tuple` of 1-D integer `Tensor`s.

    #### Example:

    >>> rt = tf.ragged.constant(
    ...     [[[[3, 1, 4, 1], [], [5, 9, 2]], [], [[6], []]]])
    >>> for i, ids in enumerate(rt.nested_value_rowids()):
    ...   print('row ids for dimension %d: %s' % (i+1, ids.numpy()))
    row ids for dimension 1: [0 0 0]
    row ids for dimension 2: [0 0 0 2 2]
    row ids for dimension 3: [0 0 0 0 2 2 2 3]

    RaggedNestedValueRowIdsN)r
   rU   rA   r4   r,   r$   rG   r   )r3   rX   rt_nested_idsr   s       r6   r{   z RaggedTensor.nested_value_rowidsx  s    : 
7$	@ "((*+m++iy,/Y3356$$	 y,/ =!" " "s   A)B
BB c                    t        j                  |d| g      5  |#| j                  j                         cddd       S t	        j
                  | j                  j                         |      cddd       S # 1 sw Y   yxY w)a
  Returns the number of rows in this ragged tensor.

    I.e., the size of the outermost dimension of the tensor.

    Args:
      out_type: `dtype` for the returned tensor.  Defaults to
        `self.row_splits.dtype`.
      name: A name prefix for the returned tensor (optional).

    Returns:
      A scalar `Tensor` with dtype `out_type`.

    #### Example:

    >>> rt = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    >>> print(rt.nrows())  # rt has 5 rows.
    tf.Tensor(5, shape=(), dtype=int64)

    RaggedNRowsNr0   )r
   rU   r1   rR   r   rE   )r3   out_typerX   s      r6   rR   zRaggedTensor.nrows  sr    ( 
mdV	4 J		""((*J J }}T00668I	J J Js   A7.A77B c                     t        j                  |d| g      5  | j                  j                         cddd       S # 1 sw Y   yxY w)a  Returns the start indices for rows in this ragged tensor.

    These indices specify where the values for each row begin in
    `self.values`.  `rt.row_starts()` is equal to `rt.row_splits[:-1]`.

    Args:
      name: A name prefix for the returned tensor (optional).

    Returns:
      A 1-D integer Tensor with shape `[nrows]`.
      The returned tensor is nonnegative, and is sorted in ascending order.

    #### Example:

    >>> rt = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    >>> print(rt.values)
    tf.Tensor([3 1 4 1 5 9 2 6], shape=(8,), dtype=int32)
    >>> print(rt.row_starts())  # indices of row starts in rt.values
    tf.Tensor([0 4 4 7 8], shape=(5,), dtype=int64)

    RaggedRowStartsN)r
   rU   r1   rd   r   s     r6   rd   zRaggedTensor.row_starts  >    , 
/$	8 .  ++-. . .r   c                     t        j                  |d| g      5  | j                  j                         cddd       S # 1 sw Y   yxY w)a  Returns the limit indices for rows in this ragged tensor.

    These indices specify where the values for each row end in
    `self.values`.  `rt.row_limits(self)` is equal to `rt.row_splits[:-1]`.

    Args:
      name: A name prefix for the returned tensor (optional).

    Returns:
      A 1-D integer Tensor with shape `[nrows]`.
      The returned tensor is nonnegative, and is sorted in ascending order.

    #### Example:

    >>> rt = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
    >>> print(rt.values)
    tf.Tensor([3 1 4 1 5 9 2 6], shape=(8,), dtype=int32)
    >>> print(rt.row_limits())  # indices of row limits in rt.values
    tf.Tensor([4 4 7 8 8], shape=(5,), dtype=int64)

    RaggedRowLimitsN)r
   rU   r1   ri   r   s     r6   ri   zRaggedTensor.row_limits  r   r   r)   c           	      R   |dk(  r| j                   j                         S |dk(  r| j                   j                         S t        j                  |d| g      5  t        j                  || j                  j                  d      }|dk(  r| j                         cddd       S |dk(  r | j                  }|dd |dd z
  cddd       S t        | j                  t              r6| j                  | j                  j                  |dz
              cddd       S t        j                  | j                  | j                   j                        }| j                  t        j                  |d|dz
   | j                   j                        ||dz
     z        cddd       S # 1 sw Y   yxY w)	a'  Returns the lengths of the rows in this ragged tensor.

    `rt.row_lengths()[i]` indicates the number of values in the
    `i`th row of `rt`.

    Args:
      axis: An integer constant indicating the axis whose row lengths should be
        returned.
      name: A name prefix for the returned tensor (optional).

    Returns:
      A potentially ragged integer Tensor with shape `self.shape[:axis]`.

    Raises:
      ValueError: If `axis` is out of bounds.

    #### Example:

    >>> rt = tf.ragged.constant(
    ...     [[[3, 1, 4], [1]], [], [[5, 9], [2]], [[6]], []])
    >>> print(rt.row_lengths())  # lengths of rows in rt
    tf.Tensor([2 0 2 1 0], shape=(5,), dtype=int64)
    >>> print(rt.row_lengths(axis=2))  # lengths of axis=2 rows.
    <tf.RaggedTensor [[3, 1], [], [2, 1], [1], []]>

    r   r)   RaggedRowLengths
rank(self))
ndims_nameNr   )r1   rR   r`   r
   rU   r   get_positive_axisr.   rankr[   r,   r4   r$   with_valuesr0   ones)r3   axisrX   r   r.   s        r6   r`   zRaggedTensor.row_lengths  sm   6 qy  &&((qy  ,,..	04&	9 ((


L:d	zz|	 
 19abzF3BK'  dkk<0 7 7q AB  d6I6I6O6OPNN5$(+T-@-@-F-FG$(O  s!   AF"FAFA<FF&c                    t        j                  |d| g      5  g }| }t        |t              r<|j	                  |j                                |j                  }t        |t              r<t        |      cddd       S # 1 sw Y   yxY w)a  Returns a tuple containing the row_lengths for all ragged dimensions.

    `rt.nested_row_lengths()` is a tuple containing the `row_lengths` tensors
    for all ragged dimensions in `rt`, ordered from outermost to innermost.

    Args:
      name: A name prefix for the returned tensors (optional).

    Returns:
      A `tuple` of 1-D integer `Tensors`.  The length of the tuple is equal to
      `self.ragged_rank`.
    RaggedNestedRowLengthsN)r
   rU   r,   r$   rG   r`   r4   r   )r3   rX   rt_nested_row_lengthsrts       r6   r   zRaggedTensor.nested_row_lengths  sv     
6	? * br<($$R^^%56YY r<( ()* * *s   AA>*
A>>Bc                 z   || j                   j                  }nt        j                  |      }t	        j
                  |d| |g      5  | j                  }| j                  }t        |t              r|dk(  r)t        j                  |d   |      d   dz
  cddd       S |dk(  rqt        j                  t        j                  | j                               d      }|| j                   j                  k7  rt        j                   ||      }|cddd       S t        j                  | j"                  |      }t        j                  ||      }|d   dz
  g|D 	cg c]4  }	t        j                  t        j                  |	dd |	dd z
        d      6 c}	z   }
|dd }|| j                   j                  k7  r#|
D cg c]  }t        j                   ||       }
}t        j$                  t'        j(                  |
      |gd      }||nt        j*                  ||      cddd       S c c}	w c c}w # 1 sw Y   yxY w)a  Returns the tight bounding box shape for this `RaggedTensor`.

    Args:
      axis: An integer scalar or vector indicating which axes to return the
        bounding box for.  If not specified, then the full bounding box is
        returned.
      name: A name prefix for the returned tensor (optional).
      out_type: `dtype` for the returned tensor.  Defaults to
        `self.row_splits.dtype`.

    Returns:
      An integer `Tensor` (`dtype=self.row_splits.dtype`).  If `axis` is not
      specified, then `output` is a vector with
      `output.shape=[self.shape.ndims]`.  If `axis` is a scalar, then the
      `output` is a scalar.  If `axis` is a vector, then `output` is a vector,
      where `output[i]` is the bounding size for dimension `axis[i]`.

    #### Example:

    >>> rt = tf.ragged.constant([[1, 2, 3, 4], [5], [], [6, 7, 8, 9], [10]])
    >>> rt.bounding_shape().numpy()
    array([5, 4])

    NRaggedBoundingBoxr   r   r)   r   r   )r1   r0   r	   as_dtyper
   rU   r   rz   r,   intr   r.   r   maximum
reduce_maxr`   rE   r[   concatr   stackgather)r3   r   rX   r   nested_splitsrt_flat_valuesr}   splits_shapeflat_values_shaper   ragged_dimensionsinner_dimensionsdbboxs                 r6   bounding_shapezRaggedTensor.bounding_shape/  s!   2 $$**h*h	1D$<	@ D,,m''n 
D#	19q!1HEaH1LD D QY##H$7$78H8H8J$KQO&,,222]]684FD D __T__xHl#//.8L'?Q./%3 

8..vabzF3BK/GH!
L3  +12.	T((..	.0A
+,HMM!X&
 
   !235E
FQPd\Ty'7'7d'C;D D"3
1D Ds:   AH1A,H1AH19H''H19H,AH1'
H11H:c                 :   t        |      }|j                  j                  d       | j                  j                  dd j	                  |j                  dd        t        |t              r| j                  j                  |j                  j                  k7  rlt        j                         st        d      |j                  t        j                        }| j                  t        j                        j!                  |      S t        || j                  d      S )a  Returns a copy of `self` with `values` replaced by `new_value`.

    Preserves cached row-partitioning tensors such as `self.cached_nrows` and
    `self.cached_value_rowids` if they have values.

    Args:
      new_values: Potentially ragged tensor to use as the `values` for the
        returned `RaggedTensor`.  Must have `rank > 0`, and must have the same
        number of rows as `self.values`.

    Returns:
      A `RaggedTensor`.  `result.rank = 1 + new_values.rank`.
      `result.ragged_rank = 1 + new_values.ragged_rank`
    r)   Nzself and new_values have mismatched row_splits dtypes; use RaggedTensor.with_row_splits_dtype() to convert them to compatible dtypes.Tr4   r5   r    )re   r.   r/   r4   rB   r,   r$   r1   r0   r[   r   r   r*   r   r	   int64r   r3   
new_valuess     r6   r   zRaggedTensor.with_valueso  s     2*=J''*KKbq33J4D4DRa4HI:|,!!Z%:%:%@%@@446 > ? 	? 33FLLAj''5AA*MM)<)<tM Mr8   c                     t        | j                  t              r*| j                  | j                  j                  |            S t        |      }| j                  |      S )a7  Returns a copy of `self` with `flat_values` replaced by `new_value`.

    Preserves cached row-partitioning tensors such as `self.cached_nrows` and
    `self.cached_value_rowids` if they have values.

    Args:
      new_values: Potentially ragged tensor that should replace
        `self.flat_values`.  Must have `rank > 0`, and must have the same number
        of rows as `self.flat_values`.

    Returns:
      A `RaggedTensor`.
      `result.rank = self.ragged_rank + new_values.rank`.
      `result.ragged_rank = self.ragged_rank + new_values.ragged_rank`.
    )r,   r2   r$   r   r4   with_flat_valuesre   r   s     r6   r   zRaggedTensor.with_flat_values  sM      $,,-dkk:::FGG3J?jJ''r8   c                    t        j                  |      }|t         j                  t         j                  fvrt	        d| d      | j
                  j                  |k(  r| S | j                  }t        |t              r6t        |j                  |      | j
                  j                  |      d      S t        || j
                  j                  |      d      S )a  Returns a copy of this RaggedTensor with the given `row_splits` dtype.

    For RaggedTensors with multiple ragged dimensions, the `row_splits` for all
    nested `RaggedTensor` objects are cast to the given dtype.

    Args:
      dtype: The dtype for `row_splits`.  One of `tf.int32` or `tf.int64`.

    Returns:
      A copy of this RaggedTensor, with the `row_splits` cast to the given
      type.
    z=Argument `row_splits` dtype must be int32 or int64. Received r(   Tr   )r	   r   int32r   r*   r1   r0   r2   r,   r$   r   
with_dtype)r3   r0   current_valuess      r6   r   z"RaggedTensor.with_row_splits_dtype  s     OOE"EV\\6<<00 ##(', - -  E)k\\N.,/55e<++66u= 
 ++66u= r8   c                     t        j                  || j                  j                  dd      }t        j                  || j                  j                  dd      }||k  st	        d| d| d      t        | ||      S )a  Merges outer_axis...inner_axis into a single dimension.

    Returns a copy of this RaggedTensor with the specified range of dimensions
    flattened into a single dimension, with elements in row-major order.

    #### Examples:

    >>> rt = tf.ragged.constant([[[1, 2], [3]], [[4, 5, 6]]])
    >>> print(rt.merge_dims(0, 1))
    <tf.RaggedTensor [[1, 2], [3], [4, 5, 6]]>
    >>> print(rt.merge_dims(1, 2))
    <tf.RaggedTensor [[1, 2, 3], [4, 5, 6]]>
    >>> print(rt.merge_dims(0, 2))
    tf.Tensor([1 2 3 4 5 6], shape=(6,), dtype=int32)

    To mimic the behavior of `np.flatten` (which flattens all dimensions), use
    `rt.merge_dims(0, -1)`.  To mimic the behavior of `tf.layers.Flatten` (which
    flattens all dimensions except the outermost batch dimension), use
    `rt.merge_dims(1, -1)`.

    Args:
      outer_axis: `int`: The first dimension in the range of dimensions to
        merge. May be negative if `self.shape.rank` is statically known.
      inner_axis: `int`: The last dimension in the range of dimensions to merge.
        May be negative if `self.shape.rank` is statically known.

    Returns:
      A copy of this tensor, with the specified dimensions merged into a
      single dimension.  The shape of the returned tensor will be
      `self.shape[:outer_axis] + [N] + self.shape[inner_axis + 1:]`, where `N`
      is the total number of slices in the merged dimensions.
    
outer_axisr   )	axis_namer   
inner_axiszExpected outer_axis (z*) to be less than or equal to inner_axis (r   )r   r   r.   r   r*   
merge_dims)r3   r   r   s      r6   r   zRaggedTensor.merge_dims  s    B ,,

	!J
 ,,

	!J
 #.zl ;//9l"> ? ?dJ
33r8   c           
      2   t        j                  |      }|j                  y|j                         }|d   +| j                  j
                  j                  |d   dz          | j                  j                  }t        | j                        D ]  \  }}||dz      }||j                  ?t        j                  |j                        }|||k(  rDt        d|dz    d| d| d      t        j                  ||      |_
        |j                   t#        j$                  |j
                  |      dz
  |_         t'        | j(                  d	      rEt        j                  dg|| j*                  dz   d z         }| j(                  j                  |       yy)
a  Updates the static shape of `self` to be `shape`.

    * If a dimension of `shape` has known rank, and is encoded via
      partitioning, then this will update the corresponding partition to
      define `_uniform_row_length` and `nrows`.
    * If a dimension of `shape` has a known rank, and is encoded as one
      of the `flat_values` dimensions, then `flat_values.set_shape()` will
      be used to update its shape.

    Warning: Using this method to assert an incorrect shape for a RaggedTensor
    (i.e., one that's not consistent with its actual shape) can cause
    segmentation faults and very difficult-to-diagnose behavior.  Only use this
    method if you are certain that the shape is correct.

    Args:
      shape: `tf.TensorShape` specifying the shape for this `RaggedTensor`.
    Nr   r)   zInconsistent size for axis : r   r(   r   	set_shape)r   as_shaper   as_listr1   _row_splitsr   r0   	enumerater   _uniform_row_lengthr   constant_valuer*   r
   convert_to_tensorrC   r   sizehasattrrz   r   )r3   r.   r0   ir;   r   old_row_length
flat_shapes           r6   
_set_shapezRaggedTensor._set_shape  s   , !!%(EzzMMOE Qx
%%//a1= %%E!$"="=> 991q5\d		((4&55++-.'~%!<QUG2"0!1tfA ? @ @(+(=(=dE(J	%#&^^##e5789)
9$ t-(($%8H8H18L8M2N)NOj
  , .r8   c           	         ! t        j                  |      }||t        d      t        |t              st        d| d      |dk  rt        d| d      t        j                  |d|||g      5  t        j                  |d	      }|j                  j                  <|j                  j                  d
k  r#t        d|j                  j                   d      |j                  j                  |dz          t        j                  ||      }|d   }|$t        |t        t        f      rt        |      rt        |d   t        t         f      s|dt        |      fvrt        dt        |       d| d      |j                  j                  t        |      dz          t#        j$                  |d         }	t        j&                  |	gt         j(                        }
| j+                  |
|d      }|j-                  d      }t        j.                  ||      }| j+                  ||d      cddd       S |dkD  rC|j                  j1                         r?|j                  j3                         }t5        j6                  |      }||dz
     g||d z   }n8t#        j6                  |      }t        j8                  ||dz
     g||d gd      }t        j:                  ||      }| j=                  ||||      }t?        |dz
  dd      D ]i  }tA        jB                  |j                  |      jD                  }|||   }ntG        jH                  ||      }tJ        jM                  ||||dz
     d      }k |cddd       S |bt        j                  |d|jN                        }|j                  jQ                  |j                  d
d        t#        jR                  ||       t        j                  |      }t#        j>                  d
|      !tU        jT                  |d
kD   !fd fd      }|jW                  tA        jX                  ddg             |jW                  |j                  dd
        t#        jZ                  |      }t#        j\                  ||      }|t        j^                  t#        j>                  d|dz         d      z  }t#        j`                  |d      }|tc        jd                  |d|      }|j                  jg                  d       t#        jh                  ||      }t#        jj                  |d      }t#        jl                  |      }t        j8                  t        jn                  dg|      |gd      }t        jp                  ||      }t        j.                  ||      }| js                  ||d      cddd       S t        j8                  |d   |d   z  g|d
d gd      }t        j:                  ||      }tA        jB                  |j                  d      jD                  }tA        jB                  |j                  d      jD                  }|tG        jH                  ||      }n|d   }|tG        jH                  ||      }n|d   }tJ        jM                  |||d      cddd       S # 1 sw Y   yxY w)a  Converts a `tf.Tensor` into a `RaggedTensor`.

    The set of absent/default values may be specified using a vector of lengths
    or a padding value (but not both).  If `lengths` is specified, then the
    output tensor will satisfy `output[row] = tensor[row][:lengths[row]]`. If
    'lengths' is a list of lists or tuple of lists, those lists will be used
    as nested row lengths. If `padding` is specified, then any row *suffix*
    consisting entirely of `padding` will be excluded from the returned
    `RaggedTensor`.  If neither `lengths` nor `padding` is specified, then the
    returned `RaggedTensor` will have no absent/default values.

    Examples:

    >>> dt = tf.constant([[5, 7, 0], [0, 3, 0], [6, 0, 0]])
    >>> tf.RaggedTensor.from_tensor(dt)
    <tf.RaggedTensor [[5, 7, 0], [0, 3, 0], [6, 0, 0]]>
    >>> tf.RaggedTensor.from_tensor(dt, lengths=[1, 0, 3])
    <tf.RaggedTensor [[5], [], [6, 0, 0]]>

    >>> tf.RaggedTensor.from_tensor(dt, padding=0)
    <tf.RaggedTensor [[5, 7], [0, 3], [6]]>

    >>> dt = tf.constant([[[5, 0], [7, 0], [0, 0]],
    ...                   [[0, 0], [3, 0], [0, 0]],
    ...                   [[6, 0], [0, 0], [0, 0]]])
    >>> tf.RaggedTensor.from_tensor(dt, lengths=([2, 0, 3], [1, 1, 2, 0, 1]))
    <tf.RaggedTensor [[[5], [7]], [], [[6, 0], [], [0]]]>

    Args:
      tensor: The `Tensor` to convert.  Must have rank `ragged_rank + 1` or
        higher.
      lengths: An optional set of row lengths, specified using a 1-D integer
        `Tensor` whose length is equal to `tensor.shape[0]` (the number of rows
        in `tensor`).  If specified, then `output[row]` will contain
        `tensor[row][:lengths[row]]`.  Negative lengths are treated as zero. You
          may optionally pass a list or tuple of lengths to this argument, which
          will be used as nested row lengths to construct a ragged tensor with
          multiple ragged dimensions.
      padding: An optional padding value.  If specified, then any row suffix
        consisting entirely of `padding` will be excluded from the returned
        RaggedTensor.  `padding` is a `Tensor` with the same dtype as `tensor`
        and with `shape=tensor.shape[ragged_rank + 1:]`.
      ragged_rank: Integer specifying the ragged rank for the returned
        `RaggedTensor`.  Must be greater than zero.
      name: A name prefix for the returned tensors (optional).
      row_splits_dtype: `dtype` for the returned `RaggedTensor`'s `row_splits`
        tensor.  One of `tf.int32` or `tf.int64`.

    Returns:
      A `RaggedTensor` with the specified `ragged_rank`.  The shape of the
      returned ragged tensor is compatible with the shape of `tensor`.

    Raises:
      ValueError: If both `lengths` and `padding` are specified.
      ValueError: If the rank of `tensor` is 0 or 1.
    Nz6Specify argument `lengths` or `padding`, but not both.0Argument `ragged_rank` must be an int. Received r(   r   z8Argument `ragged_rank` must be greater than 0. Received RaggedFromTensorr   rX      zThe rank of a RaggedTensor must be greater than 1, i.e., a list of scalars won't have ragged dimensions. Received argument `tensor` with rank r)   r   z^If Argument `lengths` is a tuple of row_lengths, argument `ragged_rank` must be len(lengths): z. Received ragged_rank: r   r   FrT   )default_valuer   )row_splits_dtype)r4   rn   rR   rK   paddingrX   r0   c                  2    t        j                         S )Nr   )r   
reduce_all)has_default_valuereduce_axiss   r6   <lambda>z*RaggedTensor.from_tensor.<locals>.<lambda>  s    H''(9L r8   c                       S N )r  s   r6   r  z*RaggedTensor.from_tensor.<locals>.<lambda>  s    % r8   r   )maxlen):r	   r   r*   r,   r   r-   r
   rU   r   r.   r   r/   r   rw   r   rv   floatr   
reduce_sumr   r>   r   	to_tensorboolean_maskis_fully_definedr   npcumprodr   reshapefrom_tensorranger   dimension_at_indexvaluer   constantr$   rq   r0   rB   equalr   r   r   logical_notrE   expand_dimsr   r   convert_to_int_tensorassert_has_rankminimumr   cumsumzerossequence_maskr\   )"rJ   r   r   r  r   rX   r  input_shaper   
num_tokens	ones_maskragged_maskdense_ragged_maskmasked_datadim_size	new_shape	flattenedr}   r   dim_lentensor_rankhas_defaulthas_nondefaultlength_for_nondefault_valuelimitsr   maskr4   values_shapeconst_nrowsconst_ncolsrR   r  r  s"                                   @@r6   r  zRaggedTensor.from_tensor.  s   B '78w2OPPk3' ""-a1 2 2a ##.-q2 3 3 
067G2L	M KP$$V(;f				&6<<+<+<q+@ M #LL--.a1 2 	2 ll%%kAo6OOF5EFk!ne 
*WtUm"D
g,z'!*sElCq#g,//  ,,/L> :++6-q: ; ; 	''Gq(89((5
NNJ<v{{C	11w 2 0'111F,,V5FG**;%*PEKP KPR 
q<<((*,,.+ ZZ,(a01K4MM)%%k2(&&q)*K,EFQP)%%fi8	w:J ! L +/1b1 
	D 33FLL$GMM'_!$'G!**74DEG77!(TAX&	 8 &
	 GKP KPL 
	'')6<<9//QR0@A
 %NN7F;  nnV,nnQ4ii!OL%' 	l66d|DEfll2A./ "--k:!~7GH!!(..EAI">BC 	$ %%&AJ		 33GY4DF%%a(""7E2""7A.)!!__aS"23V<1F&&wu=''5""66E"BqKP KPz %%N[^+,k!"o
>QHl  6f 33FLL!DJJk 33FLL!DJJk		 $$[2BCA		 $$[2BCA11E 2 PUKP KP KPs"   4G[?D?[I[C$[[c                    t        j                  |d| ||g      5  |"t        j                  |d| j                        }t	        |       }|D cg c]  }|d   	 }}|D cg c]  }|d   	 }}| t        j                  d| j                        }t        |t        t        f      r9t        d |D              r't        d	 |D              rt        j                  |      }t        ||d   j                        }t        j                   || j"                  |||
      }	| j$                  }
|
j&                  t        |t(        j*                        sst-        j.                  |      }|j&                  |
}n>t1        |j3                         |
j3                               D cg c]  \  }}||n| }}}|	j5                  |       |	cddd       S c c}w c c}w c c}}w # 1 sw Y   yxY w)a  Converts this `RaggedTensor` into a `tf.Tensor`.

    If `shape` is specified, then the result is padded and/or truncated to
    the specified shape.

    Examples:

    >>> rt = tf.ragged.constant([[9, 8, 7], [], [6, 5], [4]])
    >>> print(rt.to_tensor())
    tf.Tensor(
        [[9 8 7] [0 0 0] [6 5 0] [4 0 0]], shape=(4, 3), dtype=int32)
    >>> print(rt.to_tensor(shape=[5, 2]))
    tf.Tensor(
        [[9 8] [0 0] [6 5] [4 0] [0 0]], shape=(5, 2), dtype=int32)

    Args:
      default_value: Value to set for indices not specified in `self`. Defaults
        to zero.  `default_value` must be broadcastable to
        `self.shape[self.ragged_rank + 1:]`.
      name: A name prefix for the returned tensors (optional).
      shape: The shape of the resulting dense tensor.  In particular,
        `result.shape[i]` is `shape[i]` (if `shape[i]` is not None), or
        `self.bounding_shape(i)` (otherwise).`shape.rank` must be `None` or
        equal to `self.rank`.

    Returns:
      A `Tensor` with shape `ragged.bounding_shape(self)` and the
      values specified by the non-empty values in `self`.  Empty values are
      assigned `default_value`.
    RaggedToTensorNr  r  r   r)   r  c              3   P   K   | ]  }t        |t        j                           y wr  )r,   rt   ru   .0vs     r6   	<genexpr>z)RaggedTensor.to_tensor.<locals>.<genexpr>0  s     >1jJ--.>   $&c              3   \   K   | ]$  }t        |t        t        j                  f       & y wr  )r,   r   rt   ru   r>  s     r6   rA  z)RaggedTensor.to_tensor.<locals>.<genexpr>1  s"     E!jS*"3"345Es   *,)r.   r4   r  row_partition_typesrow_partition_tensors)r
   rU   r   r0   $_get_row_partition_type_tensor_pairsr   r&  r,   rw   r   anyallr   r   _shape_as_tensorr   ragged_tensor_to_tensorrz   r.   r   rt   ru   r   r   ry   r   r   )r3   r  rX   r.   type_tensor_pairsxrD  rE  shape_tensorr   ragged_shapeoutput_shapes1s2s                 r6   r  zRaggedTensor.to_tensor  s   > 
.}e0L	M +		"--tzzC>tD+<=aQqT==->?qt??		!DJJ7
UT5M
*
>>
>
EuE
E%%e,%e-B1-E-K-KLl(@@!!%1 5f ZZl				&z
""0
 %%e,::%, "%--/<3G3G3IJ2r Nb*,  	&W+ +
 >?>K+ +s6   4GGG!G-D1GG.GGG&c                    t        j                  |      }t        j                  |      s"t	        dt        |      j                   d      t        j                  |d|g      5  t        j                  |d      }|j                  j                  j                  d}n-|j                  j                  j                  d   j                  }|j                  j                  j                  d}n-|j                  j                  j                  d   j                  }|d	k7  r|d	k7  rt!        d
      t        j"                  t%        |j                              5  t'        j(                  |j                  dddf   |      }t'        j(                  |j                  d   |      }| j+                  |j,                  ||d      cddd       cddd       S # 1 sw Y   nxY w	 ddd       y# 1 sw Y   yxY w)a  Converts a 2D `tf.sparse.SparseTensor` to a `RaggedTensor`.

    Each row of the `output` `RaggedTensor` will contain the explicit values
    from the same row in `st_input`.  `st_input` must be ragged-right.  If not
    it is not ragged-right, then an error will be generated.

    Example:

    >>> indices = [[0, 0], [0, 1], [0, 2], [1, 0], [3, 0]]
    >>> st = tf.sparse.SparseTensor(indices=indices,
    ...                             values=[1, 2, 3, 4, 5],
    ...                             dense_shape=[4, 3])
    >>> tf.RaggedTensor.from_sparse(st).to_list()
    [[1, 2, 3], [4], [], [5]]

    Currently, only two-dimensional `SparseTensors` are supported.

    Args:
      st_input: The sparse tensor to convert.  Must have rank 2.
      name: A name prefix for the returned tensors (optional).
      row_splits_dtype: `dtype` for the returned `RaggedTensor`'s `row_splits`
        tensor.  One of `tf.int32` or `tf.int64`.

    Returns:
      A `RaggedTensor` with the same values as `st_input`.
      `output.ragged_rank = rank(st_input) - 1`.
      `output.shape = [st_input.dense_shape[0], None]`.
    Raises:
      ValueError: If the number of dimensions in `st_input` is not known
        statically, or is not two.
    zAArgument `st_input` must be of type SparseTensor, but is of type r(   RaggedFromSparsest_inputr  Nr   r)   r  zrank(st_input) must be 2.FrT   )r	   r   r   	is_sparser-   type__name__r
   rU   "convert_to_tensor_or_sparse_tensordense_shaper.   ndimsdimsr  indicesr*   control_dependencies'_assert_sparse_indices_are_ragged_rightr   rE   rV   r4   )rJ   rT  rX   r  static_rank_from_dense_shapestatic_rank_from_indicessegment_idsnum_segmentss           r6   from_sparsezRaggedTensor.from_sparseR  s   D '78""8, $$(N$;$;#<A? @ @	08*	= HAA
%h 
			#	#	)	)	1'+$'/';';'A'A'F'Fq'I'O'O$						%	%	-#' #+#3#3#9#9#>#>q#A#G#G 	%	*/G1/L455##
1(2B2B
CE H
 mmH$4$4QT$:<LM}}X%9%9!%<>NO$$OO[, % HH H#H H"H H H#H H Hs&   %C5G,A)G	G,G	G,,G5c                     t        j                  |d| g      5  t        j                  | j                  | j
                  |      }t        j                  |j                  |j                  |j                        cddd       S # 1 sw Y   yxY w)a^  Converts this `RaggedTensor` into a `tf.sparse.SparseTensor`.

    Example:

    >>> rt = tf.ragged.constant([[1, 2, 3], [4], [], [5, 6]])
    >>> print(rt.to_sparse())
    SparseTensor(indices=tf.Tensor(
                     [[0 0] [0 1] [0 2] [1 0] [3 0] [3 1]],
                     shape=(6, 2), dtype=int64),
                 values=tf.Tensor([1 2 3 4 5 6], shape=(6,), dtype=int32),
                 dense_shape=tf.Tensor([4 3], shape=(2,), dtype=int64))

    Args:
      name: A name prefix for the returned tensors (optional).

    Returns:
      A SparseTensor with the same values as `self`.
    RaggedToSparser  N)r
   rU   r   ragged_tensor_to_sparser   rz   r   SparseTensorsparse_indicessparse_valuessparse_dense_shape)r3   rX   r}   s      r6   	to_sparsezRaggedTensor.to_sparse  s|    & 
.	7 C(@@

 
 $"2"2?f''(=(=(.(<(<(.(A(ACC C Cs   A!BBc           	         t        j                  |dt        j                        }|j                  j
                  G|E|||j                  j
                  z   k7  r)t        d| d| d|j                  j
                   d      |dn|}t        j                  |d	||||g      5  t        j                  ||t        |d
      |||      }| j                  |j                  |j                  d      cddd       S # 1 sw Y   yxY w)a  Converts a `variant` Tensor into a `RaggedTensor`.

    The input `variant` could be a scalar, meaning it encodes a single
    `RaggedTensor` with ragged_rank `output_ragged_rank`. Alternatively it could
    have an arbitrary rank, in which case each element is decoded into a
    `RaggedTensor` with ragged_rank `input_ragged_rank` and these are then
    stacked according to the input shape to output a single `RaggedTensor`
    with ragged_rank `output_ragged_rank`. If `input_ragged_rank` is not
    provided, it is inferred dynamically as `output_ragged_rank` -
    `rank(variant)`. If `input_ragged_rank` is provided, the following must be
    true: `output_ragged_rank` = `input_ragged_rank` + `rank(variant)`.

    Example:

    >>> rt = tf.ragged.constant([[0], [1, 2]])
    >>> et = rt._to_variant()
    >>> stacked_et = tf.stack([et, et])
    >>> tf.RaggedTensor._from_variant(  # scalar input.
    ...     et, dtype=tf.int32, output_ragged_rank=1).to_list()
    [[0], [1, 2]]
    >>> tf.RaggedTensor._from_variant(  # batched input.
    ...     stacked_et, dtype=tf.int32, output_ragged_rank=2).to_list()
    [[[0], [1, 2]], [[0], [1, 2]]]

    Args:
      variant: A `variant` Tensor representing an encoded (possibly
        nested-batched) `RaggedTensor`.
      dtype: The dtype of the encoded `RaggedTensor`.
      output_ragged_rank: The expected ragged rank of the output `RaggedTensor`.
      input_ragged_rank: The ragged rank of each encoded `RaggedTensor`. This is
        optional and inferred dynamically if not provided.
      row_splits_dtype: `dtype` for the RaggedTensor's `row_splits` tensor. One
        of `tf.int32` or `tf.int64`.
      name: A name prefix for the returned tensors (optional).

    Returns:
      A `RaggedTensor` of dtype `dtype` and ragged rank `output_ragged_rank`.

    Raises:
      ValueError: If the input rank is known, `input_ragged_rank` is provided
          and `output_ragged_rank` = `input_ragged_rank` + `rank(variant)` does
          not hold.
    variantr  NzArgument `output_ragged_rank` (z@) must be equal to `input_ragged_rank` + `variant.shape.ndims` (z + r   r   RaggedFromVariantr   FrT   )r
   r   r	   rm  r.   rZ  r*   rU   r   ragged_tensor_from_variantmaxr   output_dense_valuesoutput_nested_splits)rJ   rm  r0   output_ragged_rankinput_ragged_rankr  rX   r}   s           r6   _from_variantzRaggedTensor._from_variant  s!   f ##iv~~7G',=,I/'--2E2EEE+,>+? @ GMM$7$7#8<= = 07=N	!	%*,>?
A 	 )CC
$c*<a&@%
D"f ''

$
$

%
% ( 	 	 	s   %AC;;Dc                     t        j                  |d| |g      5  t        j                  | j                  | j
                  ||      cddd       S # 1 sw Y   yxY w)av  Converts this `RaggedTensor` into a `variant` Tensor.

    If `batched_input` is `True`, then the `RaggedTensor` is unbatched along the
    zero-th dimension, each component `RaggedTensor` is encoded into a scalar
    `variant` Tensor, and these are stacked to return a 1-D `variant` Tensor.
    If `batched_input` is `False`, then the `RaggedTensor` is encoded as is and
    a scalar `variant` Tensor is returned.

    Example:
    >>> rt = tf.ragged.constant([[[0]], [[1]], [[2]]])
    >>> rt._to_variant().shape.as_list()
    []
    >>> rt._to_variant(batched_input=True).shape.as_list()
    [3]

    Args:
      batched_input: If `True`, the `RaggedTensor` is unbatched and converted to
        a `variant` vector. Set to `False` by default.
      name: A name prefix for the returned tensors (optional).

    Returns:
      A `variant` Tensor that encodes this `RaggedTensor`.
    RaggedToVariantN)r
   rU   r   ragged_tensor_to_variantr   rz   )r3   batched_inputrX   s      r6   _to_variantzRaggedTensor._to_variant  sW    0 
/$1F	G I&??

 
 $"2"2M4II I Is   ,AAc                     | j                         rDt        j                  dt        i      5  t        | j	                               }d d d        d dS d| j
                  d| j                  dS # 1 sw Y   ,xY w)NrH  )	formatterz<tf.RaggedTensor >ztf.RaggedTensor(values=z, row_splits=))	_is_eagerr  printoptions
_formatternumpyr4   r[   )r3   
value_texts     r6   __repr__zRaggedTensor.__repr__  su    ~~ ??eZ%89 .

-
. A..  =AKK<@OOM M	. .s   A22A;c                    | j                         st        d      | j                  j                         }| j                  j                         }t        t        |      dz
        D cg c]  }|||   ||dz        c}s1t        j                  d|j                  dd z   |j                        S t        fdD              }|rt        j                  nd}t        j                  |      S c c}w )a  Returns a numpy `array` with the values for this `RaggedTensor`.

    Requires that this `RaggedTensor` was constructed in eager execution mode.

    Ragged dimensions are encoded using numpy `arrays` with `dtype=object` and
    `rank=1`, where each element is a single row.

    #### Examples

    In the following example, the value returned by `RaggedTensor.numpy()`
    contains three numpy `array` objects: one for each row (with `rank=1` and
    `dtype=int64`), and one to combine them (with `rank=1` and `dtype=object`):

    >>> tf.ragged.constant([[1, 2, 3], [4, 5]], dtype=tf.int64).numpy()
    array([array([1, 2, 3]), array([4, 5])], dtype=object)

    Uniform dimensions are encoded using multidimensional numpy `array`s.  In
    the following example, the value returned by `RaggedTensor.numpy()` contains
    a single numpy `array` object, with `rank=2` and `dtype=int64`:

    >>> tf.ragged.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.int64).numpy()
    array([[1, 2, 3], [4, 5, 6]])

    Returns:
      A numpy `array`.
    z5RaggedTensor.numpy() is only supported in eager mode.r)   )r   r   Nr   c              3   R   K   | ]  }t        |      t        d          k7     yw)r   N)rv   )r?  rowrowss     r6   rA  z%RaggedTensor.numpy.<locals>.<genexpr>Q  s"     "L3s8s47|#;"Ls   $')r  r*   r4   r  r[   r  rv   r  r&  r.   r0   rG  object_array)r3   r4   r   r   has_variable_length_rowsr0   r  s         @r6   r  zRaggedTensor.numpy)  s    6 >>NOO[[ F__""$F5:3v;?5KLF6!9VAE]+LDXXfv||AB//v||DD  #"Lt"LL2BJJE88D&& Ms   *C4c                    t        | j                  t        j                        st	        d      | j                  j                         j                         }| j                  }t        |t              r?t        t        |      dz
        D cg c]  }|||   ||dz       j                           c}S t        |d      r|j                         j                         }n(t        |d      r|j                         }nt	        d      t        t        |      dz
        D cg c]  }|||   ||dz        c}S c c}w c c}w )zReturns a nested Python `list` with the values for this `RaggedTensor`.

    Requires that `rt` was constructed in eager execution mode.

    Returns:
      A nested Python `list`.
    z'to_list can only be used in eager mode.r)   r  to_listz$values must be convertible to a list)r,   r[   r
   EagerTensorr*   r  tolistr4   r$   r  rv   r  r   )r3   r[   r4   r   values_as_lists        r6   r  zRaggedTensor.to_listU  s#    doos7@AA&&(//1J[[F&,' Z1,- Az!a%0
1
9
9
;  
	!..069%)?@@ Z1,- Az!a%'8
9 s   #D7D<c                     | j                   j                         }t        | j                        D ]&  }t	        j
                  ||j                               }( |S )zFReturns a RaggedTensorValue for self.  Requires self._is_eager()=true.)rz   r  rx   r   r   RaggedTensorValue)r3   r  r[   s      r6   _eager_valuezRaggedTensor._eager_valueu  sR    ""$Et556 O
!33E:;K;K;MNeOLr8   c                     | }t        |t              rBt        |j                  t        j                        sy|j
                  }t        |t              rBt        |t        j                        S )zCReturns True if values & row_splits Tensors are all `EagerTensor`s.F)r,   r$   r[   r
   r  r4   )r3   r   s     r6   r  zRaggedTensor._is_eager|  sN    	B
R
&s799b R
& b#//**r8   c                       fd}|S )Nc                  &    ~ ~t        d d      )NzTYou must import 'tensorflow.python.ops.ragged.ragged_ops' before using RaggedTensor.r(   )r*   )argskwargsrX   s     r6   stubz/RaggedTensor._overloaded_operator.<locals>.stub  s&    
''+fA/0 0r8   r  )rX   r  s   ` r6   _overloaded_operatorz!RaggedTensor._overloaded_operator  s    0 Kr8   __getitem____ge____gt____le____lt____and____rand__
__invert____ror____or____xor____rxor____abs____add____radd____div____rdiv____floordiv____rfloordiv____mod____rmod____mul____rmul____neg____pow____rpow____sub____rsub____truediv____rtruediv__c                 x    | j                   }t        |t              r|j                   }t        |t              r|S )z"Convert `self` to a graph element.r   )r3   r4   s     r6   _as_graph_elementzRaggedTensor._as_graph_element  s/    [[F
V\
*}}f V\
*Mr8   c                 ,    t         j                  |       S r  )RaggedTensorSpec
from_valuer   s    r6   
_type_speczRaggedTensor._type_spec  s    &&t,,r8   c                 n    t        || j                  | j                  | j                  j                        S r  )r  r0   r   r[   )r3   r.   s     r6   _shape_invariant_to_type_specz*RaggedTensor._shape_invariant_to_type_spec  s,    E4::t/?/? OO113 3r8   c                 "    | j                         S r  )
_consumersr   s    r6   	consumerszRaggedTensor.consumers  s    ??r8   )F)T)NNT)NT)NTNr  )NN)r)   NNNN)FN)crW  
__module____qualname____doc__r#   do_not_generate_docsr7   classmethodrO   r!   add_dispatch_supportrV   r\   ra   rf   rj   rq   r~   r   r   r   r?   propertyr0   r.   r   r   r   r   r4   r   r[   rn   rz   r   rA   r{   rR   rd   ri   r`   r   r   r   r   r   r   r   r	   r   r  r  rc  rk  ru  rz  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   !WithValuesCompositeTensorGradient__composite_gradient__r  r8   r6   r$   r$   A   s)   z~ $$-( %-(f +J +JZ    #!!%8O ! 8Ot   ,O ! ,O\   (O ! (OT   %O ! %ON   #O ! #OJ    %)'+#'HO ! HOT    -1$((,; ! ;z    #'&*	& ! &P    $('+	& ! &P  (,+/	) )V $# $#T   M M*11 * C C*  .   , ,, 4 42  8 # #>06#"JJ4.2.2/b**:D@M:(,>.4`7-z    #)<<TP ! TPlJX   &*V\\ =H ! =H~C4 
 '+%+\\D DLI>M,*'X@+ %]3+)&)&)&)& +'!*-(#L1* +')& +'!*-( +' +'!*-( +'!*-(%n5,&7- +'!*-( +'!*-( +' +'!*-( +'!*-($]3+%n5, - -3 BAAC r8   c                 B    t        | t        t        j                  f      S )zBReturns true if `value` is a ragged tensor or ragged tensor value.)r,   r$   r   r  r  s    r6   	is_raggedr    s"    	E!#6#H#HI
K Kr8   c                     |j                  dd      }|rt        d| d      d}d}| D ]?  }t        |t              s|j                  j
                  t        j                  k(  rd}>d}A |rD|rBt        j                         st        d      t        j                  }t        d | D              } n#|rt        j                  }nt        j                  }|r|| fS | S )a  Return a copy of `tensors` with row_splits all having the same dtype.

  Args:
    *tensors: A list of Tensors or RaggedTensors.
    **kwargs: If 'return_dtype=True', then return a tuple (dtype, tensors),
      where `dtype` is the data type used by row-splits, and `tensors` is the
      converted list of `Tensors` and `RaggedTensors`.

  Returns:
    The converted list of `Tensors` and `RaggedTensors`.
  return_dtypeFzUnexpected keyword args r(   TzInput RaggedTensors have mismatched row_splits dtypes; use RaggedTensor.with_row_splits_dtype() to convert them to compatible dtypes.c              3   ~   K   | ]5  }t        |t              r|j                  t        j                        n| 7 y wr  )r,   r$   r   r	   r   r?  ts     r6   rA  z*match_row_splits_dtypes.<locals>.<genexpr>  s=        2<A| 2=-BC	Ds   ;=)popr*   r,   r$   r[   r0   r	   r   r   r   r   r   )tensorsr  r  	has_int32	has_int64r   r0   s          r6   match_row_splits_dtypesr    s     NE2,
/xq9
::)) f&,'				 	 FLL	0		 9224 4 5 5 LLE   G
 LLELLE7Nr8   r  ztf.RaggedTensorSpecc                   6    e Zd ZdZg dZed        Zed        Zed        Zed        Z	ed        Z
ed        Zd	ej                  d	ej                  d	fd
Z fdZd Zed        Zd Zd Zed        Zd Zd Zd Zd Zd Zd Zd Zd Zed        Z xZ S )r  z+Type specification for a `tf.RaggedTensor`.)_shape_dtype_ragged_rank_row_splits_dtype_flat_values_specc                     | j                   S )a   The `tf.dtypes.DType` specified by this type for the RaggedTensor.

    Examples:

    >>> rt = tf.ragged.constant([["a"], ["b", "c"]], dtype=tf.string)
    >>> tf.type_spec_from_value(rt).dtype
    tf.string

    Returns:
      A `tf.dtypes.DType` of the values in the RaggedTensor.
    r  r   s    r6   r0   zRaggedTensorSpec.dtype	  s     ;;r8   c                     | j                   S )a  The statically known shape of the RaggedTensor.

    Examples:

    >>> rt = tf.ragged.constant([[0], [1, 2]])
    >>> tf.type_spec_from_value(rt).shape
    TensorShape([2, None])

    >>> rt = tf.ragged.constant([[[0, 1]], [[1, 2], [3, 4]]], ragged_rank=1)
    >>> tf.type_spec_from_value(rt).shape
    TensorShape([2, None, 2])

    Returns:
      A `tf.TensorShape` containing the statically known shape of the
      RaggedTensor. Ragged dimensions have a size of `None`.
    r  r   s    r6   r.   zRaggedTensorSpec.shape)	  s    $ ;;r8   c                     | j                   S )aZ  The number of times the RaggedTensor's flat_values is partitioned.

    Defaults to `shape.ndims - 1`.

    Examples:

    >>> values = tf.ragged.constant([[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]])
    >>> tf.type_spec_from_value(values).ragged_rank
    1

    >>> rt1 = tf.RaggedTensor.from_uniform_row_length(values, 2)
    >>> tf.type_spec_from_value(rt1).ragged_rank
    2

    Returns:
      A Python `int` indicating the number of times the underlying `flat_values`
      Tensor has been partitioned to add a new dimension.
      I.e., `tf.rank(rt) = tf.rank(rt.flat_values) + rt.ragged_rank`.
    r  r   s    r6   r   zRaggedTensorSpec.ragged_rank=	  s    * r8   c                     | j                   S )aX  The `tf.dtypes.DType` of the RaggedTensor's `row_splits`.

    Examples:

    >>> rt = tf.ragged.constant([[1, 2, 3], [4]], row_splits_dtype=tf.int64)
    >>> tf.type_spec_from_value(rt).row_splits_dtype
    tf.int64

    Returns:
      A `tf.dtypes.DType` for the RaggedTensor's `row_splits` tensor. One
      of `tf.int32` or `tf.int64`.
    r  r   s    r6   r  z!RaggedTensorSpec.row_splits_dtypeT	  s     !!!r8   c                     | j                   S )zThe `TypeSpec` of the flat_values of RaggedTensor.

    Returns:
      - The TypeSpec of flat_values.
      - None when the flat_values is a Tensor.
    )r  r   s    r6   flat_values_specz!RaggedTensorSpec.flat_values_specd	  s     !!!r8   c                 L    | j                   dkD  rt        S t        j                  S Nr   )r  r$   rt   ru   r   s    r6   
value_typezRaggedTensorSpec.value_typen	  s     ,,q0<Gj6G6GGr8   Nc                    t        j                  |      | _        t        j                  |      | _        |)||j                  }n'||j                  k7  rt        d      |t        d      t        j                  |      | _        || _	        | j                  j                  }||t        d      |dz
  }|| _        t        | j                  t              st        d| d      |||k\  rt        d| d	| d
      yy)aO  Constructs a type specification for a `tf.RaggedTensor`.

    Args:
      shape: The shape of the RaggedTensor, or `None` to allow any shape.  If a
        shape is specified, then all ragged dimensions must have size `None`.
      dtype: `tf.DType` of values in the RaggedTensor.
      ragged_rank: Python integer, the number of times the RaggedTensor's
        flat_values is partitioned.  Defaults to `shape.ndims - 1`.
      row_splits_dtype: `dtype` for the RaggedTensor's `row_splits` tensor. One
        of `tf.int32` or `tf.int64`.
      flat_values_spec: TypeSpec for flat_value of the RaggedTensor. It shall be
        provided when the flat_values is a CompositeTensor rather then Tensor.
        If both `dtype` and `flat_values_spec` and  are provided, `dtype` must
        be the same as `flat_values_spec.dtype`. (experimental)
    Nz0dtype must be the same as flat_values_spec.dtypez:At least one of dtype or flat_values_spec must be providedz6Must specify ragged_rank or a shape with a known rank.r)   r  r(   zArgument `ragged_rank` (z) must be less than rank (r   )r   r   r  r	   r   r  r0   r*   r  r  rZ  r  r,   r   r-   )r3   r.   r0   r   r  r  r   s          r6   r7   zRaggedTensorSpec.__init__r	  s3   * ''.DK#__-=>D#	 &&$***KLL	
FH H//%(DK-D;;D	 6 7 	71Hk#Dd''- ""-a1 2 2 		3K= A''+fB0 1 	1 
 r8   c                    | j                   dk(  r| j                  ct        |t        j                  t        j
                  f      rjt        j
                  | j                  | j                        j                  |      S t        |t        t        f      s| j                  j                  |      S t        t        | #  |      S r  )r  r  r,   rt   ru   
TensorSpecr  r  is_compatible_withr$   r  super)r3   spec_or_value	__class__s     r6   r  z#RaggedTensorSpec.is_compatible_with	  s    A				'J--z/D/DEG&&kk4;;((:(:=(IJ-,8H)IJ%%88GG!4;MJJr8   c                     | j                   .| j                  | j                  | j                  | j                  fS | j                  | j                  | j                  | j                  | j                   fS r  )r  r  r  r  r  r   s    r6   
_serializezRaggedTensorSpec._serialize	  sh    %kk4;;(9(9$$& & kk4;;(9(9$$d&<&<> >r8   c                    | j                   dk  rD| j                  | j                  gS t        j                  | j                  | j
                        gS | j                  }|_t        j                  d g      j                  | j                  | j                   dz   d        }t        j                  || j
                        }t        j                  | j                  d      }|d n|dz   g}t        j                  d g| j                        }|t        j                  || j                        gt        | j                   dz
        D cg c]  }| c}z   }|S c c}w )Nr   r)   )r  r  rt   r  r  r  r   r   r   r  r  r  )r3   r  r   	outer_dimouter_splits_shapeinner_splits_spec_specss           r6   _component_specsz!RaggedTensorSpec._component_specs	  sG   A				+&&''%%dkk4;;?@@--&22D6:FF
++d''!+,
-/#../@$++N//Q?I"+"3$QG"--tfd6L6LM 	0$2H2HI %*$*;*;a*?$@Aq	ABE L 	Bs   	Ec                 d    t        |      r#|j                  gt        |j                        z   S |gS r  )r  rz   rw   r   r3   r  s     r6   _to_componentszRaggedTensorSpec._to_components	  s0     4(?(?#@@@Wnr8   c                 @   |d   }t        d |D              r>t        j                         s*t        |dd        D ]  }t	        j
                  ||      } nzt        |d   t        j                        r'|D cg c]  }t        j                  |       }}|d   }t        |dd        D ]%  }t        |t        j                  |d      d      }' | j                  j                  t        |t              rn|j!                  | j                         | j"                  Et%        |j&                  d      r/|j&                  j)                  | j"                  j*                         |S t        |t,        j.                        r|j)                  | j                         |S c c}w )	Nr   c              3   P   K   | ]  }t        |t        j                           y wr  )r,   r  ndarrayr  s     r6   rA  z4RaggedTensorSpec._from_components.<locals>.<genexpr>	  s     ;!Jq"**%;rB  r)   FrT   Tr   r   )rH  r   enabledrx   r   r  r,   r  r  r
   r   r$   r   r\   r  rZ  r   r  r   rz   r   r.   rt   ru   )r3   tensor_listr}   r[   r  s        r6   _from_componentsz!RaggedTensorSpec._from_components	  sh   ^F;{;;KKM QR1 K*$66vzJK 
KNBJJ	/9DEAs,,Q/EEQ QR1 *((eD
 {{$	FL	)$++&  ,9K9K9D2F



&
&t'<'<'B'B
C M fj//0%M! Fs   7Fc                 L    t        j                  d t        j                        gS r  )rt   r  r	   rm  r   s    r6   _flat_tensor_specsz#RaggedTensorSpec._flat_tensor_specs	  s     !!$788r8   c                    | j                   t        d      t        |t              rR|j                  | j
                  k7  r&t        d|j                   d| j
                   d      |j                  d      gS | j
                  dkD  r/t        d| j
                   d	t        |      j                   d      t        j                  d
|d      gS )N'Customized value_type is not supported.Ragged rank of value $ does not match ragged rank of type r(   Fry  r   'Expected a RaggedTensor if ragged rank=	 but got r  r  r*   r,   r$   r   r  rz  rV  rW  r   rx  r  s     r6   _to_tensor_listz RaggedTensorSpec._to_tensor_list	  s     )@AA%&			d//	/#E$5$5#6 7##'#4#4"5Q89 	9 e455			Q	5d6G6G5HU,,-Q0
 	

 $
<
<%u. r8   c                    | j                   t        d      t        |t              rR|j                  | j
                  k7  r&t        d|j                   d| j
                   d      |j                  d      gS | j
                  dkD  r/t        d| j
                   d	t        |      j                   d      t        j                  d
|d      gS )Nr
  r  r  r(   Tr  r   r  r  r  )r   rt_dense_valuesry  r  r  s     r6   _to_batched_tensor_listz(RaggedTensorSpec._to_batched_tensor_list
  s    )@AA%&			d//	/#E$5$5#6 7##'#4#4"5Q89 	9 d344			Q	5d6G6G5HU,,-Q0
 	

 $
<
<!5N r8   c                    | j                   t        d      t        j                  |d   | j                  | j
                  | j                        }| j                  j                  t        |t              rn|j                  | j                         | j                  Et        | j                  d      r/|j                  j                  | j                  j                         |S |j                  | j                         |S )Nr
  r   )r0   r  rs  r   )r  r*   r$   ru  r  r  r  r  rZ  r,   r   r  r   rz   r   r.   )r3   r  r}   s      r6   _from_compatible_tensor_listz-RaggedTensorSpec._from_compatible_tensor_list&
  s    )@AA''Akk//,,	 ( .F
 {{$	FL	)$++&  ,9I9I9D2F



&
&t'<'<'B'B
C M 	%Mr8   c                     | j                   t        d      t        t        j                  |g      j                  | j                        | j                  | j                  dz   | j                        S Nr
  r)   )
r  r*   r  r   r   r   r  r  r  r  )r3   
batch_sizes     r6   _batchzRaggedTensorSpec._batch9
  sd    )@AA  *.::4;;GT&&*D,B,BD Dr8   c                     | j                   t        d      t        | j                  dd  | j                  | j
                  dz
  | j                        S r  )r  r*   r  r  r  r  r  r   s    r6   _unbatchzRaggedTensorSpec._unbatch@
  sQ    )@AA
 DKKOT[[$:K:Ka:O 224 4r8   c                     | j                   S r  r  r   s    r6   _to_legacy_output_typesz(RaggedTensorSpec._to_legacy_output_typesJ
      ;;r8   c                     | j                   S r  r  r   s    r6   _to_legacy_output_shapesz)RaggedTensorSpec._to_legacy_output_shapesM
  r  r8   c                     | S r  r  r   s    r6   _to_legacy_output_classesz*RaggedTensorSpec._to_legacy_output_classesP
  s    Kr8   c                    t        |t        j                        s$t        |j                  t        j
                        rH | |j                  |j                  j                  |j                  |j                  j                        S t        j                  |j                        }|j                         j                  d       } | |j                  |j                  j                  |j                  |j                  j                  |      S )N)r.   r0   r   r  )r.   r0   r   r  r  )r,   r   r  rz   rt   ru   r.   r4   r0   r   r[   r   type_spec_from_valuer  r  )rJ   r  r  s      r6   r  zRaggedTensorSpec.from_valueS
  s    5-??@5$$j&7&78""'' ++11	3 3 #778I8IJ)224;;DA""'' ++11+- -r8   )!rW  r  r  r  	__slots__r  r0   r.   r   r  r  r  r	   float32r   r7   r  r  r  r   r  r  r  r  r  r  r  r  r!  r#  r  r  __classcell__)r  s   @r6   r  r  	  s"    4)
    &  , " " " " H H ^^ & $01d
K>  ,: 9 9.*&D4 - -r8   c           	         t        | t              rR|rN|j                  | j                        s3t	        d|j
                   d| j                  j
                   d|  d      | S t        | t        j                        rft        j                  |dg       5  t        j                  | j                  ||d      }t        j                  || j                  d	      cd
d
d
       S t        j                  | |||      S # 1 sw Y   y
xY w)aM  Converts value to a `RaggedTensor` or `Tensor`.

  * If `value` is a `RaggedTensor`, then return it as-is.
  * If `value` is a `RaggedTensorValue`, return a corresponding constant
    `RaggedTensor`.
  * Otherwise, use `convert_to_tensor` to convert `value` to a `Tensor`.

  Args:
    value: A `RaggedTensor`, a `RaggedTensorValue`, or an object whose type has
      a registered `Tensor` conversion function.
    dtype: Optional element type for the returned tensor.  If missing the type
      is inferred from the type of `value`.
    preferred_dtype: Optional element type for the returned tensor, used when
      dtype is None.  This argument has no effect if `value` is already a
      tensor, or when conversion is not possible.
    name: Optional name to use if a new `Tensor` is created.

  Returns:
    A `Tensor` or `RaggedTensor`.
  z"Tensor conversion requested dtype z for RaggedTensor with dtype r   r(   ConvertToTensorOrRaggedTensorrz   )r  r0   rS   rX   FrT   N)r,   r$   r  r0   r*   rX   r   r  r
   rU   r   rz   r   r   r   "convert_to_tensor_v2_with_dispatch)r  r0   preferred_dtyperX   rz   s        r6   "convert_to_tensor_or_ragged_tensorr-  v
  s	   0 |$U--ekk:;EJJ< H227++2B2B1C2eWAO P PL%,>>?	=r	B @))!!$	k
 00
u.. 1 @@ @ ??5_4 @ @s   AC<<Dc                 6    t        |       r| S t        | d      S )a  Converts value to supported RaggedTensor value.

  * If `value` is an object of supported value type, then return it as-is.
  * Otherwise convert it to Tensor or RaggedTensor.

  Args:
    value: An object of `Tensor`, `RaggedTensor` or registerred RaggedTensor
      value types, or an object whose type has a registered `Tensor` conversion
      function.

  Returns:
    An object of `Tensor`, `RaggedTensor` or registerred RaggedTensor
    value types
  r4   r  ) _is_supported_ragged_values_typer-  r  s    r6   re   re   
  s     &e,L-e(CCr8   c                     t        |       } | j                         }| r't        j                  || j                               }| r'|S r  )rw   r  r   r  )
componentsr  s     r6   $_ragged_tensor_value_from_componentsr2  
  s>    J*
..
%11%9IJE 		,r8   c                 F    | j                   | j                  fz   }|t        fS r  )r   rz   r2  )r   r1  s     r6   _ragged_tensor_session_fetchr4  
  s%    ##r~~&77*
:	;;r8   c                     | j                   | j                  fz   }|j                   |j                  fz   }t        ||      S r  )r   rz   ry   )feed_keyfeed_valkey_componentsval_componentss       r6   _ragged_tensor_session_feedr:  
  sA    --1E1E0GG.--1E1E0GG.	^^	,,r8   c                 6    | j                   | j                  fz   S r  )r   rz   )r6  s    r6   +_ragged_tensor_session_feed_for_partial_runr<  
  s    		#	#x';';&=	==r8   c                   j    e Zd ZdZej
                  fdZ ed       Z ed       Z	 ed       Z
d Zy)RaggedTensorTypezEncoding of a static type for a `RaggedTensor`.

  Use this type to express/declare that an output must have the type of
  `RaggedTensor`.
  c                 X    t        j                  |      }|| _        || _        || _        y)a#  Initializes a RaggedTensorType object.

    Args:
      dtype: data type of the `RaggedTensor`'s inner values.
      ragged_rank: ragged_rank of the declared `RaggedTensor`.
      row_splits_dtype: data type for the `RaggedTensor`'s row splits.
        One of: `tf.int32` or `tf.int64`.
    N)r	   r   r  r  r  )r3   r0   r   r  s       r6   r7   zRaggedTensorType.__init__
  s+     '78DK#D-Dr8   c                     | j                   S r  r  r   s    r6   r  zRaggedTensorType.<lambda>
  s
     r8   c                     | j                   S r  r  r   s    r6   r  zRaggedTensorType.<lambda>
  s    d&7&7 r8   c                     | j                   S r  r  r   s    r6   r  zRaggedTensorType.<lambda>
  s    4+A+A r8   c                 V    d| j                   d| j                  d| j                  dS )NzRaggedTensorType(, r~  )r0   r   r  r   s    r6   r  zRaggedTensorType.__repr__
  s&    -1ZZ9I9I-1-B-BD Dr8   N)rW  r  r  r  r	   r   r7   r  r0   r   r  r  r  r8   r6   r>  r>  
  s@     ;A,, . +
,%78+ABDr8   r>  c           
          | ddddf   }| dddf   }t        j                  t        j                  |dd |dd       d      }t        j                  |t        j
                  |dd d      t        j
                  |dd |dd dz               }t        j                  t        j                  t        j
                  |dd d            t        j                  |            }dd| g}t        j                  ||      gS )a/  Checks that the given SparseTensor.indices tensor is ragged-right.

  Example: `indices = [[0, 0], [0, 1], [2, 0], [3, 1]]` is not ragged right
  because the entry `[3, 1]` skips a cell.

  Args:
    indices: The SparseTensor indices to check.

  Returns:
    A list of control dependency op tensors.
  Nr   r)   r   r   z SparseTensor is not right-raggedzSparseTensor.indices =)
r   
reduce_any	not_equalr   wherer  logical_andr
  r   Assert)r\  index_prefixindex_suffixindex_prefix_changedindex_oksparse_indices_are_ragged_rightr=   s          r6   r^  r^  
  s	    CRC,B,
 ",,ab)<+<=AG __HNN<+;Q?nn\!"%|CR'81'<=?( %-$8$8(..bq)91=>(#%%!
 )*BG' 
$
$%Dg
N	OOr8   RaggedTensorToSparsec                     | j                   dd }| j                   d   }dgt        |      z  }t        j                  |      }t        j                  ||      }||gz   S )z"Gradient for RaggedTensorToSparse.Nr   )inputsrv   r   r.   r  )	opunused_sparse_indices_gradsparse_values_gradunused_sparse_shape_gradop_inputs_nested_row_splitsop_inputs_flat_valuesnested_row_splits_gradientr   flat_values_gradients	            r6   !_ragged_tensor_to_sparse_gradientr[  #  sq    
 !#		#2))B- !%v,G(HH  oo&;<"**+=+<> 
$';&<	<<r8   c                 B    t        j                  | dd  | d d z
  |      S )Nr)   r   r<   )r   assert_non_negativer   r=   s     r6   _assert_monotonic_increasingr_  7  s+    		&	&QRj6#2;
1 1r8   c                 p    t        j                  | t        j                  d| j                        |      S )Nr   r   r<   )r   rD   r   r  r0   r^  s     r6   _assert_zerora  <  s/    			k""1FLL97
L Lr8   c                 z    t        | t              r| j                  |      S t        j                  | |      d   S )Nr   r   )r,   r$   rR   r   r.   )r   r   s     r6   rC   rC   A  s3    %<<<**??6H5a88r8   c                    ||k(  r| S |dk(  r>t        | t              r.| j                  } |dz  }|dk(  r| S |dk(  rt        | t              r.t        | t              s| j                  j	                         r-| j                  j                         }|d| dgz   ||dz   d z   }n9t        j                  |       }t        j                  |d| dg||dz   d gd      }t        j                  | |      S |dkD  r,| j                  t        | j                  |dz
  |dz
              S | j                  }| j                  }t        ||      D ]  }t        |t              r-t        j                  |j                  |      }|j                  }A||z
  dz   }|j                  j	                         r2|j                  j                         }dg||d z   }t        |d|       }	nht        j                  |      }t        j                  dg||d gd      }t        j                   t        j"                  |d|       |j$                        }	t        j                  ||      }||	z  } n t        j'                  ||      S )at  Merges value[outer_axis...inner_axis] into a single dimension.

  See `RaggedTensor.merge_dims()` for more details.  This helper differs from
  `RaggedTensor.merge_dims()` in that `value` may be a dense or ragged tensor.

  Args:
    value: A `RaggedTensor` or `Tensor`
    outer_axis: `int`
    inner_axis: `int`

  Returns:
    A flattened `RaggedTensor` or `Tensor`.
  r   r)   Nr   r   )r,   r$   r4   r.   r  r   r   r   r  r   r   r[   r  r   _prodr   rE   reduce_prodr0   r\   )
r  r   r   	old_shaper/  r   
new_splitsr   shape_split	flat_sizes
             r6   r   r   H  sn    :L 	aJul;LLE!OJQl	 	aJul; 
E<	({{##%++%%'iKZ(B4/)JNO2LLi//%(i""[j!B4:>?)C
D1NiUI.. !^5<<aa@B B
 ||**J
+ d*l+##J$9$9:Fj$$j %)k				*	*	,$$,,.	D9[\22	)Ak23	OOJ/	$$rdIkl,C%D1M	MM  1[!9:J<L<LN	$$Z;j	)j'( 
	%	%j*	==r8   c                 L    t        j                  t        j                  | d      S )z-Returns the product of the numbers in a list.r)   )	functoolsreduceoperatormul)lsts    r6   rd  rd    s    			(,,Q	//r8   c                 j    | j                         rd| j                         fS d| j                         fS )zGets a row partition type tensor pair for the tail.

  If value_rowid is defined, then it is used. Otherwise, row_splits
  are used.

  Args:
    partition: a RowPartition.

  Returns:
    A list of (row_partition_type, row_partition_tensor) pairs.
  VALUE_ROWIDS
ROW_SPLITS)r@   rA   r[   )r;   s    r6   )_get_row_partition_type_tensor_pairs_tailrs    s8     ,,.I22455)..011r8   c                    | j                   }|dd D cg c]  }t        |       }}|d   j                  -d|d   j                         fd|d   j	                         fg|z   S d|d   j                         fg|z   S c c}w )aH  Gets a list of the row partitions for rt_input.

  If value_rowids are defined, then they are used. Otherwise, row_splits
  are used. If the outermost level has value_rowids defind, then nrows is
  also added.

  Args:
    rt_input: a ragged tensor.

  Returns:
    A list of (row_partition_type, row_partition_tensor) pairs.
  r)   Nr   FIRST_DIM_SIZErq  rr  )r   rs  _value_rowidsrR   rA   r[   )rt_inputr   rL  tails       r6   rF  rF    s     ..*@J12	O1
3A
6	O$	O]  ,z!}2245Z]779:<>BC C :a=33567$>> 
Ps   A=c                    |t         j                  k7  r"|t         j                  k7  rt        d| d      t	        | t
        j                        rR| j                  t         j                  k7  r3| j                  t         j                  k7  rt        j                  | |      S | S t        j                  |       } | st        j                  d|      S | j                         D cg c]  }|dn|
 } }t        j                  | |      S c c}w )a  Takes shape and coerces it to a shape as a tensor.

  If the object is already a tensor, simply passes it on (result is guaranteed
  to be int64 or int32, but not necessarily dtype).
  If not, creates a tensor of type dtype.

  Result is either a scalar equal to -1 if the shape is unknown_rank.
  Otherwise, it is a vector, where unknown dimensions are represented with a
  value of -1.

  In C++, see TensorShapeFromTensor for parsing shapes in kernels, and
  InferenceContext::MakeShapeFromShapeTensorTreatScalarAsUnknownShape, for
  use in the shape inference function.

  Args:
    shape: input to coerce from TensorShape, Tensor, None, List[Optional[Int]],
      Tuple[Optional[Int]].
    dtype: tf.int64 or tf.int32

  Returns:
    a scalar or vector tensor of dtype tf.int32 or tf.int64.
  z'Expected int64 or int32 for dtype: got r(   r   r   )r	   r   r   r*   r,   rt   ru   r0   r   rE   r   r   r   r  r   )r.   r0   rL  s      r6   rI  rI    s    . fllu4
>ugQG
HHz((){{fll"u{{fll'B]]5%((L



&%	%00-2]]_
=!)B"
=%
=			e5	11 >s   "Dc                 F   t        j                  | j                  d      j                  }|"t	        j
                  ||j                        }|S t        | t              r| j                  |j                        }|S t        j                  | |j                        d   }|S )z<Get the number of values for uniform row length constructor.r   r   )r   r  r.   r  r   r  r0   r,   r$   rR   r   )r4   rn   const_nvalsrF   s       r6   rp   rp     s    //a@FF+  .@.F.FGE
 
,	 &,'LL"4":":L;E 
, OOF-?-E-EFqIE	,r8   c                 P    t        | t              r| j                  j                  S y)z4Returns the partition dtype, or None if None exists.N)r,   r$   r1   r0   )r4   s    r6   rW   rW     s!    %  &&&	r8   c                     t        | t        j                        st        d|  d      t	        | d      st        d      t	        | d      st        d      t
        | fz  ay)a  Register the `cls` as supported value type of RaggedTenosr.

  The cls must be a subclass of CompositeTensor, and must support:
   - Spec:
     The Spec must be a `BatchableTypeSpec`
   - Properties:
     - x.shape
     - x.dtype
   - Methods:
     - x.__getitem__(idx) (method: returns a supported value type)
     - x.set_shape(shape)
   - Ops:
     - tf.shape(x) -- tf.shape(x)[0] must be a tf.Tensor.
     - tf.tile(x)
     - assert_rank_at_least(x)
     - tf.ones_like(x)
     - tf.gather(params=x, indices=Tensor)
     - tf.add(x, y)
     - tf.boolean_mask(x, ...)
     - @TODO(edloper): Complete this list

   Note: the following RaggedTensor, RaggedTensorSpec methods & ops are not
   currently supported unless `rt.values` is a RaggedTensor or a tf.Tensor:
     - rt.to_tensor()
     - rt.to_sparse_tensor()
     - rt._to_variant()
     - rt._from_variant()
     - tf.ragged.cross([rt])
     - tf.gather(params=x, indices=rt)  # rt used for indices
     - RaggedTensorSpec methods:
       - _batch
       - _unbatch
       - _to_tensor_list
       - _to_batched_tensor_list
       - _from_compatible_tensor_list

  Args:
    cls: The type to be added to supported value types.
  zcls (z() must be a subclass of CompositeTensor.r.   z&cls must support the `shape` property.r0   z&cls must support the `dtype` property.N)
issubclassr   CompositeTensorr*   r   _SUPPORTED_RAGGED_VALUE_TYPES)rJ   s    r6   _add_supported_value_typer    sd    P 
C)99	:
uSE!IJ
KK	g	
=
>>	g	
=
>>C6)r8   c                 "    t        | t              S r  )r,   r  r  s    r6   r/  r/  +  s    	E8	99r8   c                 v    t        |       s.dj                  d t        D              }t        d| d|  d      y )NrD  c              3   4   K   | ]  }|j                     y wr  )rW  )r?  rJ   s     r6   rA  z:_assert_is_supported_ragged_values_type.<locals>.<genexpr>1  s     O#Os   ztype(values) must be one of: z, got r(   )r/  joinr  r-   )r  ok_typess     r6   r+   r+   /  s?    	)%	0yyO1NOOH
3H:VE7!L
MM 
1r8   c                     t        | t        j                        r?| j                  dk7  rt        j                  | d      S t        | j                               S t        |       S )z)Separate Numpy array elements with comma.r   rD  )	separator)r,   r  r  r   array2stringreprr  str)rL  s    r6   r  r  5  sH    2::vv{__Q$// !((*q6Mr8   )
ragged_opsr  r  )fr  rk  rm  typingr  r  tensorflow.core.protobufr   tensorflow.pythonr   tensorflow.python.clientr   tensorflow.python.frameworkr   r   r   r	   r
   r   r   rt   r   r   r   r   r   tensorflow.python.opsr   r   r   r   r   r   r   tensorflow.python.ops.raggedr   r   r   *tensorflow.python.ops.ragged.row_partitionr   tensorflow.python.saved_modelr   tensorflow.python.typesr   
core_typesr    internal_typestensorflow.python.utilr!    tensorflow.python.util.tf_exportr"   tensorflow.tools.docsr#   ro   r  NativeObjectr$   r  r  registerBatchableTypeSpecr  register_codecBuiltInTypeSpecCodecTypeSpecProtoRAGGED_TENSOR_SPEC'register_type_spec_from_value_converterr  r  r-  re   r2  r4  r:  r<  )register_session_run_conversion_functionsr>  r^  RegisterGradientr[  r_  ra  r   rC   r   rd  rs  rF  rI  rp   rW   ru   r  r  r/  r+   r  UnionRagged
TensorLikeRaggedOrDenser  r  r8   r6   <module>r     s   ;     / ! , 8 A 3 . + 5 < 9 4 3 1 : + 1 + & 5 ; * 6 < 4 C @ 6 > + 6 . &<<  >R"E$$R"E R"EjDK,d 23T-!@!@T- 4 T-n
 &  % %///*22EE 2	 1 1))+;+F+FH .27;,0)XD0<
-> 2 1 1.0K/1D DB&PR ,-= .=&1
L
 #LL 9@>F0
2$?.$2N	 ",!2!2L A 
/*d:N
 
l$7$I$II	J
 VZ%:%::;
 4r8   