docstr: Takes two lists of source and target sentences, sorts them, and packs
  into batches to minimize the use of padding tokens. Returns a list of
  batches where each batch contains indices of sentences included into it
docstr_tok: ["Takes","two","lists","of","source","and","target","sentences",",","sorts","them",",","and","packs","into","batches","to","minimize","the","use","of","padding","tokens",".","Returns","a","list","of","batches","where","each","batch","contains","indices","of","sentences","included","into","it"]
code: def pack_data_into_batches(self, src_ids, tgt_ids):
      """
      Takes two lists of source and target sentences, sorts them, and packs
      into batches to minimize the use of padding tokens. Returns a list of
      batches where each batch contains indices of sentences included into it
      """
  
      # create buckets sorted by the number of src tokens
      # each bucket is also sorted by the number of tgt tokens
      buckets = {}
      for i, src_id in enumerate(src_ids):
          src_len, tgt_len = len(src_id), len(tgt_ids[i])
          if src_len not in buckets:
              buckets[src_len] = [(tgt_len, i)]
          else:
              buckets[src_len].append((tgt_len, i))
  
      for b_idx in buckets:
          buckets[b_idx] = sorted(buckets[b_idx])
  
      buckets = OrderedDict(sorted(buckets.items()))
      indices = list(buckets.keys())
  
      batches = [[]]
      num_batches = 0
      batch_size = 0
      i = 0
      src_len = 0
      tgt_len = 0
  
      while i < len(buckets):
          while buckets[indices[i]]:
              i_src = max(src_len, indices[i])
              i_tgt = max(tgt_len, buckets[indices[i]][0][0])
  
              try:
                  ip1_src = max(src_len, indices[i + 1])
                  ip1_tgt = max(tgt_len, buckets[indices[i + 1]][0][0])
              except IndexError:
                  ip1_src = i_src + 1
                  ip1_tgt = i_tgt + 1
  
              if i_src + i_tgt <= ip1_src + ip1_tgt:
                  src_len = i_src
                  tgt_len = i_tgt
                  _, idx = buckets[indices[i]].pop(0)
              else:
                  src_len = ip1_src
                  tgt_len = ip1_tgt
                  _, idx = buckets[indices[i + 1]].pop(0)
  
              batches[num_batches].append(idx)
              batch_size += 1
  
              if (
                  batch_size * (src_len + tgt_len)
                  > self.tokens_in_batch
              ):
                  num_examples_to_split = len(batches[num_batches])
                  batches_to_evict = 8 * (
                      (num_examples_to_split - 1) // 8
                  )
  
                  if batches_to_evict == 0:
                      batches_to_evict = num_examples_to_split
  
                  batches.append(
                      batches[num_batches][batches_to_evict:]
                  )
                  batches[num_batches] = batches[num_batches][
                      :batches_to_evict
                  ]
                  batch_size = num_examples_to_split - batches_to_evict
  
                  num_batches += 1
                  if batch_size > 0:
                      src_len = max(
                          [
                              len(src_ids[j])
                              for j in batches[num_batches]
                          ]
                      )
                      tgt_len = max(
                          [
                              len(tgt_ids[j])
                              for j in batches[num_batches]
                          ]
                      )
                  else:
                      src_len = 0
                      tgt_len = 0
                  break
  
          if not buckets[indices[i]]:
              i = i + 1
  
      if not batches[-1]:
          batches.pop(-1)
  
      return batches
  
imports: import io
  import json
  import pickle
  from collections import OrderedDict
  from dataclasses import dataclass
  from typing import Any, List, Optional
  import braceexpand
  import numpy
  import webdataset
  from torch.utils.data import IterableDataset
  from nemo.collections.nlp.data.data_utils.data_preprocessing import dataset_to_ids
  from nemo.core import Dataset
  from nemo.utils import logging
label_desc: Use image node_id 6 for calling the TranslationDataset obj's underlying member method code with example usage: obj.pack_data_into_batches(src_ids, tgt_ids) and returns: batches