class_docstr: A dataset that accepts as argument multiple datasets and then samples from them based on the specified 
  sampling technique.
  Args:
      datasets (list): A list of datasets to sample from.
      shuffle (bool): Whether to shuffle individual datasets. Only works with non-iterable datasets. 
          Defaults to True.
      sampling_technique (str): Sampling technique to choose which dataset to draw a sample from.
          Defaults to 'temperature'. Currently supports 'temperature', 'random' and 'round-robin'.
      sampling_temperature (int): Temperature value for sampling. Only used when sampling_technique = 'temperature'.
          Defaults to 5.
      sampling_scale: Gives you the ability to upsample / downsample the dataset. Defaults to 1.
      sampling_probabilities (list): Probability values for sampling. Only used when sampling_technique = 'random'.
      seed: Optional value to seed the numpy RNG.
      global_rank (int): Worker rank, used for partitioning map style datasets. Defaults to 0.
      world_size (int): Total number of processes, used for partitioning map style datasets. Defaults to 1.
code: def __init__(
      self,
      datasets: List[Any],
      shuffle: bool = True,
      sampling_technique: str = "temperature",
      sampling_temperature: int = 5,
      sampling_scale: int = 1,
      sampling_probabilities: List[float] = None,
      seed: Optional[int] = None,
      global_rank: int = 0,
      world_size: int = 1,
  ):
      super().__init__()
  
      supported_sampling_techniques = [
          "temperature",
          "random",
          "round-robin",
      ]
      self.datasets = datasets
      self.iterables = [None] * len(datasets)
      self.shuffle = shuffle
      self.global_rank = global_rank
      self.world_size = world_size
      self.sampling_kwargs = {}
      self.sampling_scale = sampling_scale
  
      if sampling_technique == "temperature":
          self.index_generator = ConcatDataset.temperature_generator
          self.sampling_kwargs["temperature"] = sampling_temperature
          self.sampling_kwargs["seed"] = seed
      elif sampling_technique == "random":
          self.index_generator = ConcatDataset.random_generator
          self.sampling_kwargs["p"] = sampling_probabilities
          self.sampling_kwargs["seed"] = seed
      elif sampling_technique == "round-robin":
          self.index_generator = ConcatDataset.round_robin_generator
      else:
          raise ValueError(
              f"Currently we only support sampling techniques in {supported_sampling_techniques}."
          )
      self.length = 0
  
      if isinstance(datasets[0], IterableDataset):
          self.kind = "iterable"
      else:
          self.kind = "map"
  
      for idx, dataset in enumerate(datasets):
          isiterable = isinstance(dataset, IterableDataset)
          if (isiterable and not self.kind == "iterable") or (
              not isiterable and self.kind == "iterable"
          ):
              raise ValueError(
                  "All datasets in ConcatDataset must be of the same kind (Iterable or Map)."
              )
  
          if self.kind == "map":
              self.length += len(dataset) // world_size
          else:
              self.length += len(dataset)
  
      if self.sampling_scale != 1:
          self.length = int(self.length * self.sampling_scale)
          logging.info(
              f"applying {sampling_scale} sampling scale, concat ds len: {self.length}"
          )
  
imports: import io
  import logging
  from typing import Any, List, Optional, Tuple, Union
  import numpy
  import torch
  import torch.utils.data
  from torch.utils.data import Dataset, IterableDataset
label_desc: Use image node_id 1 to create a new ConcatDataset object from inherited base classes: IterableDataset with example: obj = ConcatDataset(datasets, shuffle, sampling_technique, sampling_temperature, sampling_scale, sampling_probabilities, seed, global_rank, world_size)