code: def create_lazy_generic_benchmark(
      train_generator: LazyStreamDefinition,
      test_generator: LazyStreamDefinition,
      *,
      other_streams_generators: Optional[
          Dict[str, LazyStreamDefinition]
      ] = None,
      complete_test_set_only: bool = False,
      train_transform=None,
      train_target_transform=None,
      eval_transform=None,
      eval_target_transform=None,
      other_streams_transforms: Optional[
          Dict[str, Tuple[Any, Any]]
      ] = None,
  ) -> GenericCLScenario:
      """
      Creates a lazily-defined benchmark instance given a dataset generator for
      each stream.
  
      Generators must return properly initialized instances of
      :class:`AvalancheDataset` which will be used to create experiences.
  
      The created datasets can have transformations already set.
      However, if transformations are shared across all datasets of the same
      stream, it is recommended to use the `train_transform`, `eval_transform`
      and `other_streams_transforms` parameters, so that transformations groups
      can be correctly applied (transformations are lazily added atop the datasets
      returned by the generators).
  
      This function allows for the creation of custom streams as well.
      While "train" and "test" streams must be always set, the generators
      for other streams can be defined by using the `other_streams_generators`
      parameter.
  
      :param train_generator: A proper lazy-generation definition for the training
          stream. It is recommended to pass an instance
          of :class:`LazyStreamDefinition`. See its description for more details.
      :param test_generator: A proper lazy-generation definition for the test
          stream. It is recommended to pass an instance
          of :class:`LazyStreamDefinition`. See its description for more details.
      :param other_streams_generators: A dictionary describing the content of
          custom streams. Keys must be valid stream names (letters and numbers,
          not starting with a number) while the value must be a
          lazy-generation definition (like the ones of the training and
          test streams). If this dictionary contains the definition for
          "train" or "test" streams then those definition will override the
          `train_generator` and `test_generator` parameters.
      :param complete_test_set_only: If True, only the complete test set will
          be returned by the benchmark. This means that the ``test_generator``
          parameter must define a stream with a single experience (the complete
          test set). Defaults to False.
      :param train_transform: The transformation to apply to the training data,
          e.g. a random crop, a normalization or a concatenation of different
          transformations (see torchvision.transform documentation for a
          comprehensive list of possible transformations). Defaults to None.
      :param train_target_transform: The transformation to apply to training
          patterns targets. Defaults to None.
      :param eval_transform: The transformation to apply to the test data,
          e.g. a random crop, a normalization or a concatenation of different
          transformations (see torchvision.transform documentation for a
          comprehensive list of possible transformations). Defaults to None.
      :param eval_target_transform: The transformation to apply to test
          patterns targets. Defaults to None.
      :param other_streams_transforms: Transformations to apply to custom
          streams. If no transformations are defined for a custom stream,
          then "train" transformations will be used. This parameter must be a
          dictionary mapping stream names to transformations. The transformations
          must be a two elements tuple where the first element defines the
          X transformation while the second element is the Y transformation.
          Those elements can be None. If this dictionary contains the
          transformations for "train" or "test" streams then those transformations
          will override the `train_transform`, `train_target_transform`,
          `eval_transform` and `eval_target_transform` parameters.
  
      :returns: A lazily-initialized :class:`GenericCLScenario` instance.
      """
  
      transform_groups = dict(
          train=(train_transform, train_target_transform),
          eval=(eval_transform, eval_target_transform),
      )
  
      if other_streams_transforms is not None:
          for (
              stream_name,
              stream_transforms,
          ) in other_streams_transforms.items():
              if isinstance(stream_transforms, Sequence):
                  if len(stream_transforms) == 1:
                      # Suppose we got only the transformation for X values
                      stream_transforms = (stream_transforms[0], None)
              else:
                  # Suppose it's the transformation for X values
                  stream_transforms = (stream_transforms, None)
  
              transform_groups[stream_name] = stream_transforms
  
      input_streams = dict(train=train_generator, test=test_generator)
  
      if other_streams_generators is not None:
          input_streams = {**input_streams, **other_streams_generators}
  
      if complete_test_set_only:
          if input_streams["test"][1] != 1:
              raise ValueError(
                  "Test stream must contain one experience when"
                  "complete_test_set_only is True"
              )
  
      stream_definitions: Dict[
          str,
          Tuple[
              # Dataset generator + stream length
              Tuple[
                  Generator[TaskAwareClassificationDataset, None, None],
                  int,
              ],
              # Task label(s) for each experience
              Iterable[Union[int, Iterable[int]]],
          ],
      ] = dict()
  
      for stream_name, (
          generator,
          stream_length,
          task_labels,
      ) in input_streams.items():
          initial_transform_group = "train"
          if stream_name in transform_groups:
              initial_transform_group = stream_name
  
          adapted_stream_generator = _adapt_lazy_stream(
              generator,
              transform_groups,
              initial_transform_group=initial_transform_group,
          )
  
          stream_definitions[stream_name] = (
              (adapted_stream_generator, stream_length),
              task_labels,
          )
  
      return GenericCLScenario(
          stream_definitions=stream_definitions,
          complete_test_set_only=complete_test_set_only,
      )
  
file_path: avalanche/avalanche/benchmarks/scenarios/deprecated/generic_benchmark_creation.py
imports: from pathlib import Path
  from typing import Generator, List, Mapping, Sequence, Union, Any, Tuple, Dict, Optional, Iterable, NamedTuple
  from avalanche.benchmarks.utils.classification_dataset import _make_taskaware_tensor_classification_dataset, _make_taskaware_classification_dataset
  from avalanche.benchmarks.utils import SupportedDataset, FilelistDataset, PathsDataset, common_paths_root
  from avalanche.benchmarks.utils.classification_dataset import TaskAwareClassificationDataset
  from avalanche.benchmarks.scenarios.deprecated.classification_scenario import GenericCLScenario
label_desc: Use image node_id 3 for calling a global function with example usage: create_lazy_generic_benchmark(train_generator, test_generator) and returns: GenericCLScenario