def _make_taskaware_tensor_classification_dataset(
    *dataset_tensors: Sequence,
    transform: Optional[XTransform] = None,
    target_transform: Optional[YTransform] = None,
    transform_groups: Optional[Dict[str, Tuple[XTransform, YTransform]]] = None,
    initial_transform_group: Optional[str] = "train",
    task_labels: Optional[Union[int, Sequence[int]]] = None,
    targets: Optional[Union[Sequence[TTargetType], int]] = None,
    collate_fn: Optional[Callable[[List], Any]] = None
) -> Union[TaskAwareClassificationDataset, TaskAwareSupervisedClassificationDataset]:
    """Creates a ``AvalancheTensorDataset`` instance.

    A Dataset that wraps existing ndarrays, Tensors, lists... to provide
    basic Dataset functionalities. Very similar to TensorDataset from PyTorch,
    this Dataset also supports transformations, slicing, advanced indexing,
    the targets field and all the other goodies listed in
    :class:`AvalancheDataset`.

    :param dataset_tensors: Sequences, Tensors or ndarrays representing the
        content of the dataset.
    :param transform: A function/transform that takes in a single element
        from the first tensor and returns a transformed version.
    :param target_transform: A function/transform that takes a single
        element of the second tensor and transforms it.
    :param transform_groups: A dictionary containing the transform groups.
        Transform groups are used to quickly switch between training and
        eval (test) transformations. This becomes useful when in need to
        test on the training dataset as test transformations usually don't
        contain random augmentations. ``AvalancheDataset`` natively supports
        the 'train' and 'eval' groups by calling the ``train()`` and
        ``eval()`` methods. When using custom groups one can use the
        ``with_transforms(group_name)`` method instead. Defaults to None,
        which means that the current transforms will be used to
        handle both 'train' and 'eval' groups (just like in standard
        ``torchvision`` datasets).
    :param initial_transform_group: The name of the transform group
        to be used. Defaults to 'train'.
    :param task_labels: The task labels for each pattern. Must be a sequence
        of ints, one for each pattern in the dataset. Alternatively can be a
        single int value, in which case that value will be used as the task
        label for all the instances. Defaults to None, which means that a
        default task label 0 will be applied to all patterns.
    :param targets: The label of each pattern. Defaults to None, which
        means that the targets will be retrieved from the second tensor of
        the dataset. Otherwise, it can be a sequence of values containing
        as many elements as the number of patterns.
    :param collate_fn: The function to use when slicing to merge single
        patterns. In the future this function may become the function
        used in the data loading process, too.
    """
    if len(dataset_tensors) < 1:
        raise ValueError("At least one sequence must be passed")

    if targets is None:
        targets = dataset_tensors[1]
    elif isinstance(targets, int):
        targets = dataset_tensors[targets]
    tts = []
    for tt in dataset_tensors:  # TorchTensor requires a pytorch tensor
        if not hasattr(tt, "size"):
            tt = torch.tensor(tt)
        tts.append(tt)
    dataset = _TensorClassificationDataset(*tts)

    transform_gs = _init_transform_groups(
        transform_groups,
        transform,
        target_transform,
        initial_transform_group,
        dataset,
    )
    targets_data = _init_targets(dataset, targets)
    task_labels_data = _init_task_labels(dataset, task_labels)
    if initial_transform_group is not None and isinstance(dataset, AvalancheDataset):
        dataset = dataset.with_transforms(initial_transform_group)

    das = []
    for d in [targets_data, task_labels_data]:
        if d is not None:
            das.append(d)

    # Check if supervision data has been added
    is_supervised = targets_data is not None and task_labels_data is not None

    if is_supervised:
        return TaskAwareSupervisedClassificationDataset(
            [dataset],
            data_attributes=das if len(das) > 0 else None,
            transform_groups=transform_gs,
            collate_fn=collate_fn,
        )
    else:
        return TaskAwareClassificationDataset(
            [dataset],
            data_attributes=das if len(das) > 0 else None,
            transform_groups=transform_gs,
            collate_fn=collate_fn,
        )
Creates a ``AvalancheTensorDataset`` instance.

    A Dataset that wraps existing ndarrays, Tensors, lists... to provide
    basic Dataset functionalities. Very similar to TensorDataset from PyTorch,
    this Dataset also supports transformations, slicing, advanced indexing,
    the targets field and all the other goodies listed in
    :class:`AvalancheDataset`.

    :param dataset_tensors: Sequences, Tensors or ndarrays representing the
        content of the dataset.
    :param transform: A function/transform that takes in a single element
        from the first tensor and returns a transformed version.
    :param target_transform: A function/transform that takes a single
        element of the second tensor and transforms it.
    :param transform_groups: A dictionary containing the transform groups.
        Transform groups are used to quickly switch between training and
        eval (test) transformations. This becomes useful when in need to
        test on the training dataset as test transformations usually don't
        contain random augmentations. ``AvalancheDataset`` natively supports
        the 'train' and 'eval' groups by calling the ``train()`` and
        ``eval()`` methods. When using custom groups one can use the
        ``with_transforms(group_name)`` method instead. Defaults to None,
        which means that the current transforms will be used to
        handle both 'train' and 'eval' groups (just like in standard
        ``torchvision`` datasets).
    :param initial_transform_group: The name of the transform group
        to be used. Defaults to 'train'.
    :param task_labels: The task labels for each pattern. Must be a sequence
        of ints, one for each pattern in the dataset. Alternatively can be a
        single int value, in which case that value will be used as the task
        label for all the instances. Defaults to None, which means that a
        default task label 0 will be applied to all patterns.
    :param targets: The label of each pattern. Defaults to None, which
        means that the targets will be retrieved from the second tensor of
        the dataset. Otherwise, it can be a sequence of values containing
        as many elements as the number of patterns.
    :param collate_fn: The function to use when slicing to merge single
        patterns. In the future this function may become the function
        used in the data loading process, too.
    
avalanche/benchmarks/utils/classification_dataset.py