class_docstr: A TFUniformReplayBuffer with batched adds and uniform sampling.
class_docstr_tok: ["A","TFUniformReplayBuffer","with","batched","adds","and","uniform","sampling","."]
docstr: Returns an item or batch of items sampled uniformly from the buffer.
  
  Sample transitions uniformly from replay buffer. When sub-episodes are
  desired, specify num_steps, although note that for the returned items to
  truly be sub-episodes also requires that experience collection be
  single-threaded.
  
  Args:
    sample_batch_size: (Optional.) An optional batch_size to specify the
      number of items to return. See get_next() documentation.
    num_steps: (Optional.)  Optional way to specify that sub-episodes are
      desired. See get_next() documentation.
    time_stacked: Bool, when true and num_steps > 1 get_next on the buffer
      would return the items stack on the time dimension. The outputs would be
      [B, T, ..] if sample_batch_size is given or [T, ..] otherwise.
  
  Returns:
    A 2 tuple, containing:
      - An item, sequence of items, or batch thereof sampled uniformly
        from the buffer.
      - BufferInfo NamedTuple, containing:
        - The items' ids.
        - The sampling probability of each item.
  Raises:
    ValueError: if num_steps is bigger than the capacity.
docstr_tok: ["Returns","an","item","or","batch","of","items","sampled","uniformly","from","the","buffer",".","Sample","transitions","uniformly","from","replay","buffer",".","When","sub-episodes","are","desired",",","specify","num_steps",",","although","note","that","for","the","returned","items","to","truly","be","sub-episodes","also","requires","that","experience","collection","be","single-threaded",".","Args",":","sample_batch_size",":","(","Optional",".",")","An","optional","batch_size","to","specify","the","number","of","items","to","return",".","See","get_next","(",")","documentation",".","num_steps",":","(","Optional",".",")","Optional","way","to","specify","that","sub-episodes","are","desired",".","See","get_next","(",")","documentation",".","time_stacked",":","Bool",",","when","true","and","num_steps",">","1","get_next","on","the","buffer","would","return","the","items","stack","on","the","time","dimension",".","The","outputs","would","be","[","B",",","T",",","..","]","if","sample_batch_size","is","given","or","[","T",",","..","]","otherwise",".","Returns",":","A","2","tuple",",","containing",":","-","An","item",",","sequence","of","items",",","or","batch","thereof","sampled","uniformly","from","the","buffer",".","-","BufferInfo","NamedTuple",",","containing",":","-","The","items","'","ids",".","-","The","sampling","probability","of","each","item",".","Raises",":","ValueError",":","if","num_steps","is","bigger","than","the","capacity","."]
code: def _get_next(
      self, sample_batch_size=None, num_steps=None, time_stacked=True
  ):
      """Returns an item or batch of items sampled uniformly from the buffer.
  
      Sample transitions uniformly from replay buffer. When sub-episodes are
      desired, specify num_steps, although note that for the returned items to
      truly be sub-episodes also requires that experience collection be
      single-threaded.
  
      Args:
        sample_batch_size: (Optional.) An optional batch_size to specify the
          number of items to return. See get_next() documentation.
        num_steps: (Optional.)  Optional way to specify that sub-episodes are
          desired. See get_next() documentation.
        time_stacked: Bool, when true and num_steps > 1 get_next on the buffer
          would return the items stack on the time dimension. The outputs would be
          [B, T, ..] if sample_batch_size is given or [T, ..] otherwise.
  
      Returns:
        A 2 tuple, containing:
          - An item, sequence of items, or batch thereof sampled uniformly
            from the buffer.
          - BufferInfo NamedTuple, containing:
            - The items' ids.
            - The sampling probability of each item.
      Raises:
        ValueError: if num_steps is bigger than the capacity.
      """
      with tf.device(self._device), tf.name_scope(self._scope):
          with tf.name_scope("get_next"):
              min_val, max_val = _valid_range_ids(
                  self._get_last_id(), self._max_length, num_steps
              )
              rows_shape = (
                  ()
                  if sample_batch_size is None
                  else (sample_batch_size,)
              )
              assert_nonempty = tf.compat.v1.assert_greater(
                  max_val,
                  min_val,
                  message=(
                      "TFUniformReplayBuffer is empty. Make sure to add items "
                      "before sampling the buffer."
                  ),
              )
              with tf.control_dependencies([assert_nonempty]):
                  num_ids = max_val - min_val
                  probability = tf.cond(
                      pred=tf.equal(num_ids, 0),
                      true_fn=lambda: 0.0,
                      false_fn=lambda: 1.0
                      / tf.cast(
                          num_ids
                          * self._batch_size,  # pylint: disable=g-long-lambda
                          tf.float32,
                      ),
                  )
                  ids = tf.random.uniform(
                      rows_shape,
                      minval=min_val,
                      maxval=max_val,
                      dtype=tf.int64,
                  )
  
              # Move each id sample to a random batch.
              batch_offsets = tf.random.uniform(
                  rows_shape,
                  minval=0,
                  maxval=self._batch_size,
                  dtype=tf.int64,
              )
              batch_offsets *= self._max_length
  
              if num_steps is None:
                  rows_to_get = (
                      tf.math.mod(ids, self._max_length) + batch_offsets
                  )
                  data = self._data_table.read(rows_to_get)
                  data_ids = self._id_table.read(rows_to_get)
              else:
                  if time_stacked:
                      step_range = tf.range(num_steps, dtype=tf.int64)
                      if sample_batch_size:
                          step_range = tf.reshape(
                              step_range, [1, num_steps]
                          )
                          step_range = tf.tile(
                              step_range, [sample_batch_size, 1]
                          )
                          ids = tf.tile(
                              tf.expand_dims(ids, -1), [1, num_steps]
                          )
                          batch_offsets = batch_offsets[:, None]
                      else:
                          step_range = tf.reshape(
                              step_range, [num_steps]
                          )
  
                      rows_to_get = (
                          tf.math.mod(
                              step_range + ids, self._max_length
                          )
                          + batch_offsets
                      )
                      data = self._data_table.read(rows_to_get)
                      data_ids = self._id_table.read(rows_to_get)
                  else:
                      data = []
                      data_ids = []
                      for step in range(num_steps):
                          steps_to_get = (
                              tf.math.mod(ids + step, self._max_length)
                              + batch_offsets
                          )
                          items = self._data_table.read(steps_to_get)
                          data.append(items)
                          data_ids.append(
                              self._id_table.read(steps_to_get)
                          )
                      data = tuple(data)
                      data_ids = tuple(data_ids)
              probabilities = tf.fill(rows_shape, probability)
  
              buffer_info = BufferInfo(
                  ids=data_ids, probabilities=probabilities
              )
      return data, buffer_info
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import collections
  import gin
  import numpy
  import tensorflow
  from tf_agents.replay_buffers import replay_buffer
  from tf_agents.replay_buffers import table
  from tf_agents.specs import tensor_spec
  from tf_agents.utils import common
  from tf_agents.utils import nest_utils
label_desc: Use image node_id 8 for calling the TFUniformReplayBuffer obj's underlying member method code with example usage: obj._get_next(sample_batch_size, num_steps, time_stacked) and returns: data,  buffer_info