class_docstr: A dataloader used to load :class:`AvalancheDataset`s for which
  the FFCV support was previously enabled by using :func:`enable_ffcv`.
  
  This is not a pure wrapper of a FFCV loader: this hybrid dataloader
  is in charge of both creating the FFCV loader and merging
  the Avalanche-specific info contained in the :class:`DataAttribute`
  fields of the datasets (such as task labels).
class_docstr_tok: ["A","dataloader","used","to","load",":","class",":","`","AvalancheDataset","`","s","for","which","the","FFCV","support","was","previously","enabled","by","using",":","func",":","`","enable_ffcv","`",".","This","is","not","a","pure","wrapper","of","a","FFCV","loader",":","this","hybrid","dataloader","is","in","charge","of","both","creating","the","FFCV","loader","and","merging","the","Avalanche-specific","info","contained","in","the",":","class",":","`","DataAttribute","`","fields","of","the","datasets","(","such","as","task","labels",")","."]
code: def __iter__(self):
      from avalanche.benchmarks.utils.ffcv_support.ffcv_epoch_iterator import (
          _CustomEpochIterator,
      )
  
      get_item_dataset = self.get_item_dataset
  
      # Instantiate the FFCV loader
      if self._persistent_loader is not None:
          ffcv_loader = self._persistent_loader
  
          if not self.persistent_workers:
              # Corner case:
              # This may happen if start_immediately is True
              # but persistent_workers is False
              self._persistent_loader = None
      else:
          ffcv_loader = self._make_loader()
  
          if self.persistent_workers:
              self._persistent_loader = ffcv_loader
  
      epoch_iterator: "_CustomEpochIterator" = iter(ffcv_loader)
  
      for indices, batch in epoch_iterator:
          # Before returning the batch, obtain the custom Avalanche values
          # and add it to the batch.
          # Those are the values not found in the FFCV dataset
          # (and not stored on disk!).
          #
          # A common element is the task label, which is usually returned
          # as the third element.
          #
          # In practice, those fields are "data attributes"
          # of the input AvalancheDataset whose `use_in_getitem`
          # field is True.
          #
          # This means in practice:
          # 1. obtain the `batch` from FFCV (usually is a tuple `x, y`).
          # 2. obtain the Avalanche values such as `t` (or others).
          #   We do this through the `get_item_dataset`.
          # 3. create an overall tuple `x, y, t, ...`.
  
          elements_from_attributes = get_item_dataset[indices]
  
          elements_from_attributes_device = []
  
          for element in elements_from_attributes:
              if isinstance(element, torch.Tensor):
                  element = element.to(self.device, non_blocking=True)
              elements_from_attributes_device.append(element)
  
          overall_batch = tuple(batch) + tuple(
              elements_from_attributes_device
          )
  
          yield overall_batch
  
imports: from dataclasses import dataclass
  from pathlib import Path
  from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Union
  from collections import OrderedDict
  import warnings
  import numpy
  import torch
  from torch.utils.data.sampler import Sampler
  from avalanche.benchmarks.scenarios.generic_scenario import CLScenario
  from avalanche.benchmarks.utils.data import AvalancheDataset
  from avalanche.benchmarks.utils.dataset_traversal_utils import flat_datasets_from_benchmark, single_flat_dataset
  from avalanche.benchmarks.utils.utils import concat_datasets
label_desc: Use image node_id 4 for calling the HybridFfcvLoader obj's underlying member method code with example usage: obj.__iter__() without return types