class_docstr: The implement of DialogReader.
docstr: Construct a batch reader.
docstr_tok: ["Construct","a","batch","reader","."]
code: def _batch_reader(
      self, reader, phase=None, is_infer=False, sort_pool_size=2**16
  ):
      """Construct a batch reader."""
  
      def update_max_lens(max_lens, record):
          """Update max_lens."""
          if max_lens is None:
              return self.sort_key(record)
          else:
              return [
                  max(max_len, l)
                  for max_len, l in zip(max_lens, self.sort_key(record))
              ]
  
      def get_batch(reader):
          """Generate batches from reader."""
          batch, max_lens = [], None
          for record in reader():
              if record is None:
                  yield batch
                  batch, max_lens = [], None
                  continue
  
              self.current_example += 1
              max_lens = update_max_lens(max_lens, record)
              if self.in_tokens:
                  to_append = (len(batch) + 1) * sum(
                      max_lens
                  ) <= self.batch_size
              else:
                  to_append = len(batch) < self.batch_size
              if to_append:
                  batch.append(record)
              else:
                  yield batch
                  batch, max_lens = [record], self.sort_key(record)
  
          if len(batch) > 0:
              yield batch
  
      def get_sorted_batch(pool):
          """Generate sorted batches from pool."""
          pool = sorted(pool, key=self.sort_key)
          batches = []
          batch, max_lens = [], None
          for record in pool:
              self.current_example += 1
              max_lens = update_max_lens(max_lens, record)
              if self.in_tokens:
                  to_append = (len(batch) + 1) * sum(
                      max_lens
                  ) <= self.batch_size
              else:
                  to_append = len(batch) < self.batch_size
              if to_append:
                  batch.append(record)
              else:
                  batches.append(batch)
                  batch, max_lens = [record], self.sort_key(record)
  
          if len(batch) > 0:
              batches.append(batch)
          self.global_rng.shuffle(batches)
  
          for batch in batches:
              yield batch
  
      def __wrapper__():
          if sort_pool_size > 0:
              pool = []
              for record in reader():
                  pool.append(record)
                  if len(pool) == sort_pool_size:
                      for batch in get_sorted_batch(pool):
                          yield batch
                      pool = []
              if len(pool) > 0:
                  for batch in get_sorted_batch(pool):
                      yield batch
          else:
              for batch in get_batch(reader):
                  yield batch
  
      return __wrapper__
  
imports: import csv
  from collections import namedtuple
  from contextlib import contextmanager
  import gzip
  import numpy
  from ..utils import pad_batch_data
  from ..utils.args import str2bool
  from ..utils.masking import mask
  from ..utils import tokenization
label_desc: Use image node_id 9 for calling the DialogReader obj's underlying member method code with example usage: obj._batch_reader(reader, phase, is_infer, sort_pool_size) and returns: __wrapper__, self, unknown