docstr: Calculation of next batch is performed using following logic.
  
  Current chosen iterator is set in the change_dataloader function
  based on the chosen iteration strategy which is called everytime
  prepare_batch is called.
  
  If we get the next batch from iterator without any StopIteration exception,
  we return it as it is. Otherwise, we have two cases:
  
  1. In some iteration strategies (example size proportional), each dataset
  needs to same number of epochs at any given time, we need to yield
  StopIteration exception when all iterators are finished. In turn, this
  will yield to __iter__ all reignite all of the iterators. The code will
  not reach __iter__ until unless all iterators are exhausted. An iteration
  strategy should specify this behavior through `should_exhaust_all_iterators`
  property
  
  2. In other cases of iteration strategies, epochs don't make sense.
  Think of a case of random (equal) proportional sampling for dataset x and y
  where x is half the size of y. When x will complete its 2 epochs, y will
  have only 1 epoch completed. **So please don't use max_epochs or epoch
  based training in this case as it won't be honored**. If an iterator is
  finished, we just reignite it in this case and finished iterators
  variable isn't used. This means that this case will never reach the
  __iter__ function ever again.
  
  
  Returns:
      SampleList: sample list instance from currently selected dataset
docstr_tok: ["Calculation","of","next","batch","is","performed","using","following","logic",".","Current","chosen","iterator","is","set","in","the","change_dataloader","function","based","on","the","chosen","iteration","strategy","which","is","called","everytime","prepare_batch","is","called",".","If","we","get","the","next","batch","from","iterator","without","any","StopIteration","exception",",","we","return","it","as","it","is",".","Otherwise",",","we","have","two","cases",":","1",".","In","some","iteration","strategies","(","example","size","proportional",")",",","each","dataset","needs","to","same","number","of","epochs","at","any","given","time",",","we","need","to","yield","StopIteration","exception","when","all","iterators","are","finished",".","In","turn",",","this","will","yield","to","__iter__","all","reignite","all","of","the","iterators",".","The","code","will","not","reach","__iter__","until","unless","all","iterators","are","exhausted",".","An","iteration","strategy","should","specify","this","behavior","through","`","should_exhaust_all_iterators","`","property","2",".","In","other","cases","of","iteration","strategies",",","epochs","do","n't","make","sense",".","Think","of","a","case","of","random","(","equal",")","proportional","sampling","for","dataset","x","and","y","where","x","is","half","the","size","of","y",".","When","x","will","complete","its","2","epochs",",","y","will","have","only","1","epoch","completed",".","*","*","So","please","do","n't","use","max_epochs","or","epoch","based","training","in","this","case","as","it","wo","n't","be","honored","*","*",".","If","an","iterator","is","finished",",","we","just","reignite","it","in","this","case","and","finished","iterators","variable","is","n't","used",".","This","means","that","this","case","will","never","reach","the","__iter__","function","ever","again",".","Returns",":","SampleList",":","sample","list","instance","from","currently","selected","dataset"]
code: def __next__(self) -> SampleList:
      """Calculation of next batch is performed using following logic.
  
      Current chosen iterator is set in the change_dataloader function
      based on the chosen iteration strategy which is called everytime
      prepare_batch is called.
  
      If we get the next batch from iterator without any StopIteration exception,
      we return it as it is. Otherwise, we have two cases:
  
      1. In some iteration strategies (example size proportional), each dataset
      needs to same number of epochs at any given time, we need to yield
      StopIteration exception when all iterators are finished. In turn, this
      will yield to __iter__ all reignite all of the iterators. The code will
      not reach __iter__ until unless all iterators are exhausted. An iteration
      strategy should specify this behavior through `should_exhaust_all_iterators`
      property
  
      2. In other cases of iteration strategies, epochs don't make sense.
      Think of a case of random (equal) proportional sampling for dataset x and y
      where x is half the size of y. When x will complete its 2 epochs, y will
      have only 1 epoch completed. **So please don't use max_epochs or epoch
      based training in this case as it won't be honored**. If an iterator is
      finished, we just reignite it in this case and finished iterators
      variable isn't used. This means that this case will never reach the
      __iter__ function ever again.
  
  
      Returns:
          SampleList: sample list instance from currently selected dataset
      """
      try:
          next_batch = next(self.current_iterator)
      except StopIteration:
          if self.iteration_strategy.should_exhaust_all_iterators:
              self._finished_iterators[self.current_dataset_name] = 1
  
              if len(self._finished_iterators) == self.num_datasets:
                  raise
              else:
                  self.change_dataloader()
              next_batch = next(self.current_iterator)
          else:
              iterator = iter(self.current_loader)
              self.iterators[self.current_dataset_name] = iterator
              next_batch = next(self.current_iterator)
  
      # Save dataset name and dataset type beforehand as
      # prepare_data will change the current index
      current_dataset_name = self.current_dataset_name
      current_dataset_type = self.current_dataset.dataset_type
  
      next_batch = self.prepare_batch(next_batch)
      next_batch = convert_batch_to_sample_list(next_batch)
  
      next_batch.dataset_name = current_dataset_name
      next_batch.dataset_type = current_dataset_type
      return next_batch
  
imports: import logging
  import warnings
  from typing import Dict, Iterator
  import torch
  from mmf.common.sample import convert_batch_to_sample_list, SampleList
  from mmf.datasets import iteration_strategies
  from mmf.utils.build import build_dataloader_and_sampler, build_dataset
  from mmf.utils.dataset import dataset_list_from_config
  from mmf.utils.distributed import broadcast_scalar, get_world_size, is_dist_initialized, is_main, is_xla
  from mmf.utils.general import get_batch_size, get_current_device
  from omegaconf import OmegaConf
  from torch.utils.data.dataloader import DataLoader, Sampler
label_desc: Use image node_id 19 for calling the MultiDataLoader obj's underlying member method code with example usage: obj.__next__() and returns: next_batch