class_docstr: This class is a wrapper for iterating over datasets for multiple or similar tasks, typically useful for
  multi-task training.
  `task_name` and `sampler_config` are two mandatory keys that allows us to use task-specific data samplers.
  For specifying batch sizes, we use `train_batch_size0`, and `val_batch_size0` as keys for
  training and validation sets. Note that the batch sizes are scaled automatically depending on the number of GPUs.
  
  Args:
      opts: Command-line arguments
      data_samplers: dictionary containing different samplers
  
  Example::
  # Example yaml config for combining different samplers is given below.
  # Please note that configuration for each sampler should start with `-` in `chain_sampler`.
  
  sampler:
      name: "chain_sampler"
      chain_sampler_mode: "sequential"
      chain_sampler:
        - task_name: "segmentation"
          train_batch_size0: 10
          sampler_config:
            name: "variable_batch_sampler"
            use_shards: false
            num_repeats: 4
            truncated_repeat_aug_sampler: false
            vbs:
              crop_size_width: 512
              crop_size_height: 512
              max_n_scales: 25
              min_crop_size_width: 256
              max_crop_size_width: 768
              min_crop_size_height: 256
              max_crop_size_height: 768
              check_scale: 16
        - task_name: "classification"
          train_batch_size0: 20
          sampler_config:
            name: "batch_sampler"
            bs:
              crop_size_width: 512
              crop_size_height: 512
docstr: Assuming we have samples from N datasets, then this function yields a batch from first dataset,
  then a batch from second dataset, and so on. In other words, batches are sampled from N datasets
  in a round-robin fashion.
  
  Example:
      Dataset 1: [A, B, C]
      Dataset 2: [D, E, F, G, H]
  
      The result of this sampler would be [A, D, B, E, C, F, G, H]
docstr_tok: ["Assuming","we","have","samples","from","N","datasets",",","then","this","function","yields","a","batch","from","first","dataset",",","then","a","batch","from","second","dataset",",","and","so","on",".","In","other","words",",","batches","are","sampled","from","N","datasets","in","a","round-robin","fashion",".","Example",":","Dataset","1",":","[","A",",","B",",","C","]","Dataset","2",":","[","D",",","E",",","F",",","G",",","H","]","The","result","of","this","sampler","would","be","[","A",",","D",",","B",",","E",",","C",",","F",",","G",",","H","]"]
code: def _interleave_sampling(self) -> List[Tuple]:
      """Assuming we have samples from N datasets, then this function yields a batch from first dataset,
      then a batch from second dataset, and so on. In other words, batches are sampled from N datasets
      in a round-robin fashion.
  
      Example:
          Dataset 1: [A, B, C]
          Dataset 2: [D, E, F, G, H]
  
          The result of this sampler would be [A, D, B, E, C, F, G, H]
      """
  
      items = self.samplers_dict.items()
      task_names, sampler_names = zip(*items)
      num_active_samplers = len(sampler_names)
      next_samplers = itertools.cycle(
          iter(data_sampler).__next__ for data_sampler in sampler_names
      )
  
      while num_active_samplers:
          try:
              for i, next_sampler in enumerate(next_samplers):
                  yield [
                      x + (task_names[i % num_active_samplers],)
                      for x in next_sampler()
                  ]
          except StopIteration:
              # Remove the sampler that we just exhausted from the cycle.
              num_active_samplers -= 1
              next_samplers = itertools.cycle(
                  itertools.islice(next_samplers, num_active_samplers)
              )
  
imports: from __future__ import annotations
  import argparse
  import copy
  import itertools
  import json
  from typing import Iterator, List, Mapping, Optional, Tuple
  from torch.utils.data.sampler import Sampler
  from data.sampler import SAMPLER_REGISTRY, build_sampler
  from options.utils import flatten_yaml_as_dict
  from utils import logger
label_desc: Use image node_id 5 for calling the ChainSampler obj's underlying member method code with example usage: obj._interleave_sampling() without return types