class_docstr: Iterate over datasets and provide a batch per dataset in each mini-batch.
class_docstr_tok: ["Iterate","over","datasets","and","provide","a","batch","per","dataset","in","each","mini-batch","."]
code: def __iter__(self):
      number_of_datasets = len(self.datasets)
      samplers_list = []
      sampler_iterators = []
  
      for dataset_idx in range(number_of_datasets):
          sampler = self.samplers[dataset_idx]
          samplers_list.append(sampler)
          cur_sampler_iterator = sampler.__iter__()
          sampler_iterators.append(cur_sampler_iterator)
  
      index_offsets = np.array([0] + self.cumulative_sizes[:-1])
  
      while True:
          per_dataset_indices: List[Optional[np.ndarray]] = [
              None
          ] * number_of_datasets
  
          if self.never_ending:
              sampling_dataset_order = list(range(number_of_datasets))
              is_termination_dataset = [False] * number_of_datasets
          else:
              # Obtain the indices for the "main" dataset first
              sampling_dataset_order = [
                  self.termination_dataset_idx
              ] + list(
                  x
                  for x in range(number_of_datasets)
                  if x != self.termination_dataset_idx
              )
              is_termination_dataset = [True] + (
                  [False] * (number_of_datasets - 1)
              )
  
          for dataset_idx, is_term_dataset in zip(
              sampling_dataset_order, is_termination_dataset
          ):
              sampler = samplers_list[dataset_idx]
              sampler_iterator = sampler_iterators[dataset_idx]
  
              if sampler is None:
                  continue
  
              if len(sampler) == 0:
                  if is_term_dataset and (not self.never_ending):
                      return
  
                  samplers_list[dataset_idx] = None
                  sampler_iterators[dataset_idx] = None
                  continue
  
              should_stop_if_ended = (
                  is_term_dataset or not self.oversample_small_datasets
              ) and (not self.never_ending)
  
              (
                  continue_epoch,
                  updated_iterator,
                  next_batch_indices,
              ) = self._next_batch(
                  sampler,
                  sampler_iterator,
                  stop_on_last_batch=should_stop_if_ended,
              )
  
              if not continue_epoch:
                  if is_term_dataset:
                      # The main dataset terminated -> exit
                      return
                  else:
                      # Not the main dataset
                      # Happens if oversample_small_tasks is False
                      # Remove the dataset and sampler from the list
                      samplers_list[dataset_idx] = None
                      sampler_iterators[dataset_idx] = None
                      continue
  
              assert next_batch_indices is not None
              next_batch_indices = np.array(next_batch_indices)
  
              # Shift indices according to the position of the
              # dataset in the list
              next_batch_indices += index_offsets[dataset_idx]
  
              sampler_iterators[dataset_idx] = updated_iterator
              per_dataset_indices[dataset_idx] = next_batch_indices
          per_dataset_indices = [
              x for x in per_dataset_indices if x is not None
          ]
          yield np.concatenate(per_dataset_indices).tolist()
  
imports: from typing import Any, Dict, Iterator, List, Optional, Sequence, Sized, Union
  import numpy
  from torch.utils.data import DistributedSampler, Dataset
  from torch.utils.data.dataloader import DataLoader
  from avalanche.benchmarks.utils.data import AvalancheDataset
  from avalanche.benchmarks.utils.data_attribute import DataAttribute
  from avalanche.benchmarks.utils.ffcv_support.ffcv_components import HybridFfcvLoader, has_ffcv_support
  from avalanche.distributed.distributed_helper import DistributedHelper
  from torch.utils.data.sampler import Sampler, BatchSampler
  from torch.utils.data import ConcatDataset
label_desc: Use image node_id 3 for calling the MultiDatasetSampler obj's underlying member method code with example usage: obj.__iter__() without return types