parameters: (sequence,
                                     sparse_tensor_keys,
                                     tensor_op_list,
                                     batch_size,
                                     num_unroll)
return_statement: return
docstring: Inverse of _deconstruct_sparse_tensor_seq.
  
    Given a dict of keys -> `Tensor` reconstructs `SparseTensor` values for keys
    in `sparse_tensor_keys`. Their `Tensor` values are assumed to be IDs into the
    underlying `SparseTensorsMap`. The `dense_shape` of the `SparseTensor`s is
    `[batch_size, num_unroll, d_0, d_1, ..., d_n]` when the original
    `SparseTensor` that got deconstructed with `_deconstruct_sparse_tensor_seq`
    has a `dense_shape` of `[None, d_0, d_1, ..., d_n]`.
  
    Args:
      sequence: dictionary with only `Tensor` values that is being updated.
      sparse_tensor_keys: list of the keys present in `sequence` identifying
        `SparseTensor` values that should be reconstructed.
      tensor_op_list: list of the same length as `sparse_tensor_keys` with
        `Tensor` objects.
      batch_size: int or int32 scalar `Tensor`, how large minibatches should
        be.
      num_unroll: Python integer, how many time steps were unrolled at a time.
docstring_summary: Inverse of _deconstruct_sparse_tensor_seq.
docstring_tokens: Inverse of _deconstruct_sparse_tensor_seq .
function: def _reconstruct_sparse_tensor_seq(sequence,
                                     sparse_tensor_keys,
                                     tensor_op_list,
                                     batch_size,
                                     num_unroll):
    """Inverse of _deconstruct_sparse_tensor_seq.
  
    Given a dict of keys -> `Tensor` reconstructs `SparseTensor` values for keys
    in `sparse_tensor_keys`. Their `Tensor` values are assumed to be IDs into the
    underlying `SparseTensorsMap`. The `dense_shape` of the `SparseTensor`s is
    `[batch_size, num_unroll, d_0, d_1, ..., d_n]` when the original
    `SparseTensor` that got deconstructed with `_deconstruct_sparse_tensor_seq`
    has a `dense_shape` of `[None, d_0, d_1, ..., d_n]`.
  
    Args:
      sequence: dictionary with only `Tensor` values that is being updated.
      sparse_tensor_keys: list of the keys present in `sequence` identifying
        `SparseTensor` values that should be reconstructed.
      tensor_op_list: list of the same length as `sparse_tensor_keys` with
        `Tensor` objects.
      batch_size: int or int32 scalar `Tensor`, how large minibatches should
        be.
      num_unroll: Python integer, how many time steps were unrolled at a time.
    """
    def _flatten_tensor(tensor):
      """Flattens `Tensor` of `shape [batch_size, num_unroll]` into 1D `Tensor`.
  
      The main use of this function is to work around the limitation of
      `_restore_sparse` to only accept 1D handles.
  
      Args:
        tensor: 2D `Tensor` of `shape [batch_size, num_unroll]`
      Returns:
        1D `Tensor`.
      """
      return array_ops.reshape(tensor, [-1])
  
    def _unflatten_sparse_tensor(sp_tensor):
      """Recreates `[batch_size, num_unroll]` dimensions in the `SparseTensor`.
  
      Counter-part of `_flatten_tensor` which is called on the input of
      `_restore_sparse` while this method is called on the output of it.
      Together they work around the limitation of `_restore_sparse` to only
      accept 1D handles.
  
      The `indices` in `sp_tensor` is a 2D `Tensor` of `shape [N, ndims]`, where
      `N` is the number of `values` and `ndims` is the number of dimension in its
      dense counterpart. Among `ndims` the first entry corresponds to the batch
      dimension `[0, num_unroll * batch_size)` from which we need to recreate the
      2 dimensions `batch_size` and `num_unroll`.
  
      The reason this reconstruction works is because the output of
      `_restore_sparse` despite being a `SparseTensor` is actually dense w.r.t.
      that first entry.
  
      Args:
        sp_tensor: A SparseTensor.
      Returns:
        A SparseTensor with a +1 higher rank than the input.
      """
      idx_batch = math_ops.to_int64(
          math_ops.floor(sp_tensor.indices[:, 0] / num_unroll))
      idx_time = math_ops.mod(sp_tensor.indices[:, 0], num_unroll)
      indices = array_ops.concat(
          [
              array_ops.expand_dims(idx_batch, 1),
              array_ops.expand_dims(idx_time, 1), sp_tensor.indices[:, 1:]
          ],
          axis=1)
      dense_shape = array_ops.concat(
          [[math_ops.cast(batch_size, dtype=dtypes.int64)],
           [math_ops.cast(num_unroll, dtype=dtypes.int64)],
           sp_tensor.dense_shape[1:]], axis=0)
      return sparse_tensor.SparseTensor(
          indices=indices,
          values=sp_tensor.values,
          dense_shape=dense_shape)
  
    if not sparse_tensor_keys:
      return
    tensor_list = [sequence[k] for k in sparse_tensor_keys]
    sp_tensors = [
        _restore_sparse(sparse_map_op=i,
                        # Flatten the 2D Tensor [batch_size, num_unroll] of
                        # handles to a 1D Tensor.
                        # Reconstruct the dimensions later.
                        # TODO(b/34247140): Remove this workaround.
                        sparse_handles=_flatten_tensor(s), rank=None)
        for i, s in zip(tensor_op_list, tensor_list)]
    num_unroll = ops.convert_to_tensor(num_unroll, dtype=dtypes.int64,
                                       name="num_unroll_int64")
  
    # Recreate the [batch_size, num_unroll] dimensions in the SparseTensors.
    # The dense_shape will have a +1 higher rank.
    # TODO(b/34247140): Remove this workaround.
    sp_tensors_higher_dim = [_unflatten_sparse_tensor(s) for s in sp_tensors]
  
    # Set values to SparseTensors for sparse_tensor_keys.
    for i, key in enumerate(sparse_tensor_keys):
      sequence[key] = sp_tensors_higher_dim[i]
    return
function_tokens: def _reconstruct_sparse_tensor_seq ( sequence , sparse_tensor_keys , tensor_op_list , batch_size , num_unroll ) : def _flatten_tensor ( tensor ) : """Flattens `Tensor` of `shape [batch_size, num_unroll]` into 1D `Tensor`.
  
      The main use of this function is to work around the limitation of
      `_restore_sparse` to only accept 1D handles.
  
      Args:
        tensor: 2D `Tensor` of `shape [batch_size, num_unroll]`
      Returns:
        1D `Tensor`.
      """ return array_ops . reshape ( tensor , [ - 1 ] ) def _unflatten_sparse_tensor ( sp_tensor ) : """Recreates `[batch_size, num_unroll]` dimensions in the `SparseTensor`.
  
      Counter-part of `_flatten_tensor` which is called on the input of
      `_restore_sparse` while this method is called on the output of it.
      Together they work around the limitation of `_restore_sparse` to only
      accept 1D handles.
  
      The `indices` in `sp_tensor` is a 2D `Tensor` of `shape [N, ndims]`, where
      `N` is the number of `values` and `ndims` is the number of dimension in its
      dense counterpart. Among `ndims` the first entry corresponds to the batch
      dimension `[0, num_unroll * batch_size)` from which we need to recreate the
      2 dimensions `batch_size` and `num_unroll`.
  
      The reason this reconstruction works is because the output of
      `_restore_sparse` despite being a `SparseTensor` is actually dense w.r.t.
      that first entry.
  
      Args:
        sp_tensor: A SparseTensor.
      Returns:
        A SparseTensor with a +1 higher rank than the input.
      """ idx_batch = math_ops . to_int64 ( math_ops . floor ( sp_tensor . indices [ : , 0 ] / num_unroll ) ) idx_time = math_ops . mod ( sp_tensor . indices [ : , 0 ] , num_unroll ) indices = array_ops . concat ( [ array_ops . expand_dims ( idx_batch , 1 ) , array_ops . expand_dims ( idx_time , 1 ) , sp_tensor . indices [ : , 1 : ] ] , axis = 1 ) dense_shape = array_ops . concat ( [ [ math_ops . cast ( batch_size , dtype = dtypes . int64 ) ] , [ math_ops . cast ( num_unroll , dtype = dtypes . int64 ) ] , sp_tensor . dense_shape [ 1 : ] ] , axis = 0 ) return sparse_tensor . SparseTensor ( indices = indices , values = sp_tensor . values , dense_shape = dense_shape ) if not sparse_tensor_keys : return tensor_list = [ sequence [ k ] for k in sparse_tensor_keys ] sp_tensors = [ _restore_sparse ( sparse_map_op = i , # Flatten the 2D Tensor [batch_size, num_unroll] of # handles to a 1D Tensor. # Reconstruct the dimensions later. # TODO(b/34247140): Remove this workaround. sparse_handles = _flatten_tensor ( s ) , rank = None ) for i , s in zip ( tensor_op_list , tensor_list ) ] num_unroll = ops . convert_to_tensor ( num_unroll , dtype = dtypes . int64 , name = "num_unroll_int64" ) # Recreate the [batch_size, num_unroll] dimensions in the SparseTensors. # The dense_shape will have a +1 higher rank. # TODO(b/34247140): Remove this workaround. sp_tensors_higher_dim = [ _unflatten_sparse_tensor ( s ) for s in sp_tensors ] # Set values to SparseTensors for sparse_tensor_keys. for i , key in enumerate ( sparse_tensor_keys ) : sequence [ key ] = sp_tensors_higher_dim [ i ] return