class_docstr: RandomizedBatchSamplerIterator randomly samples from each dataset
  using the provided weights.
  
  By default, the iterator stops after all datasets are exhausted. This can be changed
  by setting another stopping mechanism.
  
  Returns batches of the format: {dataloader_name: batch_from_dataloader}
  
  Args:
      individual_dataloaders (Mapping[str, Union[DataLoader, Iterable]]): A mapping of DataLoaders or Iterables with dataloader name as key
      and dataloader/iterable object as value.
      iteration_strategy (RandomizedBatchSampler): A RandomizedBatchSampler dataclass indicating how the dataloaders are iterated over.
  
  Examples:
      >>> loaders = {'a': torch.utils.data.DataLoader(range(4), batch_size=4),
          'b': torch.utils.data.DataLoader(range(15), batch_size=5)}
      >>> randomized_batch_sampler = RandomizedBatchSampler(
              stopping_mechanism=StoppingMechanism.ALL_DATASETS_EXHAUSTED
          )
      >>> combined_iterator = RandomizedBatchSamplerIterator(loaders, randomized_batch_sampler)
      >>> for item in combined_iterator:
              print(item)
      {'b': tensor([0, 1, 2, 3, 4])}
      {'b': tensor([5, 6, 7, 8, 9])}
      {'a': tensor([0, 1, 2, 3])}
      {'b': tensor([10, 11, 12, 13, 14])}
code: def __next__(self) -> Dict[str, Any]:
      if (
          self.stopping_mechanism
          == StoppingMechanism.SMALLEST_DATASET_EXHAUSTED
          and any(self._iterator_is_exhausted)
      ):
          raise StopIteration
      elif (
          self.stopping_mechanism
          == StoppingMechanism.ALL_DATASETS_EXHAUSTED
          and all(self._iterator_is_exhausted)
      ):
          raise StopIteration
      elif (
          self.stopping_mechanism
          == StoppingMechanism.RESTART_UNTIL_ALL_DATASETS_EXHAUSTED
          and len(self._iterators_finished)
          == len(self._individual_iterators)
      ):
          raise StopIteration
  
      iterator_names = self._iterator_names
      iterator_weights = self._iterator_weights
  
      if (
          self.stopping_mechanism
          != StoppingMechanism.WRAP_AROUND_UNTIL_KILLED
          and iterator_weights is not None
      ):
          iterator_names = [
              name
              for name, exhausted in zip(
                  iterator_names, self._iterator_is_exhausted
              )
              if not exhausted
          ]
          iterator_weights = [
              weight
              for weight, exhausted in zip(
                  iterator_weights, self._iterator_is_exhausted
              )
              if not exhausted
          ]
  
      selected_key = random.choices(
          iterator_names, weights=iterator_weights
      )[0]
  
      if (
          self.enforce_same_loader_across_ranks
          and dist.is_available()
          and dist.is_initialized()
      ):
          key_idx = self._iterator_names_dict[selected_key]
          dist.broadcast(key_idx, 0, group=self._process_group)
          # pyre-fixme[6]: For 1st param expected `SupportsIndex` but got
          #  `Union[bool, float, int]`.
          selected_key = self._iterator_names[key_idx.item()]
  
      try:
          batch = next(self._individual_iterators[selected_key])
      except StopIteration:
          if (
              self.stopping_mechanism
              == StoppingMechanism.RESTART_UNTIL_ALL_DATASETS_EXHAUSTED
          ):
              if selected_key not in self._iterators_finished:
                  self._iterators_finished.append(selected_key)
              if len(self._iterators_finished) == len(
                  self._individual_iterators
              ):
                  raise StopIteration
              else:
                  self._individual_iterators[selected_key] = iter(
                      self._individual_dataloaders[selected_key]
                  )
              batch = next(self._individual_iterators[selected_key])
          elif (
              self.stopping_mechanism
              == StoppingMechanism.WRAP_AROUND_UNTIL_KILLED
          ):
              self._individual_iterators[selected_key] = iter(
                  self._individual_dataloaders[selected_key]
              )
              batch = next(self._individual_iterators[selected_key])
          else:
              selected_index = self._iterator_names.index(selected_key)
              self._iterator_is_exhausted[selected_index] = True
              return next(self)
  
      return {selected_key: batch}
  
imports: from __future__ import annotations
  import random
  from abc import abstractmethod
  from dataclasses import dataclass
  from enum import Enum
  from itertools import cycle
  from typing import Any, Dict, Iterable, Iterator, List, Mapping, MutableMapping, Optional, Type, TYPE_CHECKING, Union
  import torch
  import torch.distributed
label_desc: Use image node_id 2 for calling the RandomizedBatchSamplerIterator obj's underlying member method code with example usage: obj.__next__() and returns: dict, next