class_docstr: A runner class to train and evaluate a model given a task and datasets.
  
  The runner uses pytorch distributed data parallel by default. Future release
  will support other distributed frameworks.
class_docstr_tok: ["A","runner","class","to","train","and","evaluate","a","model","given","a","task","and","datasets",".","The","runner","uses","pytorch","distributed","data","parallel","by","default",".","Future","release","will","support","other","distributed","frameworks","."]
docstr: A property to get and create dataloaders by split just in need.
  
  If no train_dataset_ratio is provided, concatenate map-style datasets and
  chain wds.DataPipe datasets separately. Training set becomes a tuple
  (ConcatDataset, ChainDataset), both are optional but at least one of them is
  required. The resultant ConcatDataset and ChainDataset will be sampled evenly.
  
  If train_dataset_ratio is provided, create a MultiIterLoader to sample
  each dataset by ratios during training.
  
  Currently do not support multiple datasets for validation and test.
  
  Returns:
      dict: {split_name: (tuples of) dataloader}
code: def dataloaders(self) -> dict:
      """
      A property to get and create dataloaders by split just in need.
  
      If no train_dataset_ratio is provided, concatenate map-style datasets and
      chain wds.DataPipe datasets separately. Training set becomes a tuple
      (ConcatDataset, ChainDataset), both are optional but at least one of them is
      required. The resultant ConcatDataset and ChainDataset will be sampled evenly.
  
      If train_dataset_ratio is provided, create a MultiIterLoader to sample
      each dataset by ratios during training.
  
      Currently do not support multiple datasets for validation and test.
  
      Returns:
          dict: {split_name: (tuples of) dataloader}
      """
      if self._dataloaders is None:
          # reoganize datasets by split and concatenate/chain if necessary
          dataset_ratios = self.config.run_cfg.get(
              "train_dataset_ratios", None
          )
  
          # concatenate map-style datasets and chain wds.DataPipe datasets separately
          # training set becomes a tuple (ConcatDataset, ChainDataset), both are
          # optional but at least one of them is required. The resultant ConcatDataset
          # and ChainDataset will be sampled evenly.
          logging.info(
              "dataset_ratios not specified, datasets will be concatenated (map-style datasets) or chained (webdataset.DataPipeline)."
          )
  
          datasets = reorg_datasets_by_split(self.datasets)
          self.datasets = concat_datasets(datasets)
  
          # print dataset statistics after concatenation/chaining
          for split_name in self.datasets:
              if isinstance(
                  self.datasets[split_name], tuple
              ) or isinstance(self.datasets[split_name], list):
                  # mixed wds.DataPipeline and torch.utils.data.Dataset
                  num_records = sum(
                      [
                          len(d)
                          if not type(d)
                          in [wds.DataPipeline, ChainDataset]
                          else 0
                          for d in self.datasets[split_name]
                      ]
                  )
  
              else:
                  if hasattr(self.datasets[split_name], "__len__"):
                      # a single map-style dataset
                      num_records = len(self.datasets[split_name])
                  else:
                      # a single wds.DataPipeline
                      num_records = -1
                      logging.info(
                          "Only a single wds.DataPipeline dataset, no __len__ attribute."
                      )
  
              if num_records >= 0:
                  logging.info(
                      "Loaded {} records for {} split from the dataset.".format(
                          num_records, split_name
                      )
                  )
  
          # create dataloaders
          split_names = sorted(self.datasets.keys())
  
          datasets = [self.datasets[split] for split in split_names]
          is_trains = [
              split in self.train_splits for split in split_names
          ]
  
          batch_sizes = [
              self.config.run_cfg.batch_size_train
              if split == "train"
              else self.config.run_cfg.batch_size_eval
              for split in split_names
          ]
  
          collate_fns = []
          for dataset in datasets:
              if isinstance(dataset, tuple) or isinstance(
                  dataset, list
              ):
                  collate_fns.append(
                      [getattr(d, "collater", None) for d in dataset]
                  )
              else:
                  collate_fns.append(getattr(dataset, "collater", None))
  
          dataloaders = self.create_loaders(
              datasets=datasets,
              num_workers=self.config.run_cfg.num_workers,
              batch_sizes=batch_sizes,
              is_trains=is_trains,
              collate_fns=collate_fns,
              dataset_ratios=dataset_ratios,
          )
  
          self._dataloaders = {
              k: v for k, v in zip(split_names, dataloaders)
          }
  
      return self._dataloaders
  
imports: import datetime
  import json
  import logging
  import os
  import time
  from pathlib import Path
  import torch
  import torch.distributed
  import webdataset
  from lavis.common.dist_utils import download_cached_file, get_rank, get_world_size, is_main_process, main_process
  from lavis.common.registry import registry
  from lavis.common.utils import is_url
  from lavis.datasets.data_utils import concat_datasets, reorg_datasets_by_split
  from lavis.datasets.datasets.dataloader_utils import IterLoader, MultiIterLoader, PrefetchLoader
  from torch.nn.parallel import DistributedDataParallel
  from torch.utils.data import DataLoader, DistributedSampler
  from torch.utils.data.dataset import ChainDataset
label_desc: Use image node_id 8 for calling the RunnerBase obj's underlying member method code with example usage: obj.dataloaders() and returns: self