code: def _create_dataset(
      uri,
      batch_size,
      shuffle,
      no_image_normalization,
      cache_dir,
      overwrite_cache,
      create_cache_explicitly,
      prepare_data_iterator,
      dataset_index,
  ):
      class Dataset:
          pass
  
      dataset = Dataset()
      dataset.uri = uri
      dataset.cache_dir = cache_dir
      dataset.normalize = not no_image_normalization
  
      comm = current_communicator()
  
      # use same random state for each process until slice is called
      # different random state is used for each dataset
      rng = numpy.random.RandomState(dataset_index)
      use_memory_cache = comm.size == 1 if comm else True
  
      if prepare_data_iterator:
          if cache_dir == "":
              cache_dir = None
  
          # Disable implicit cache creation when MPI is available.
          if cache_dir and (create_cache_explicitly or comm):
              cache_index = os.path.join(cache_dir, "cache_index.csv")
              if not os.path.exists(cache_index) or overwrite_cache:
                  create_cache_flag = False
                  if single_or_rankzero():
                      create_cache_flag = True
                      os.makedirs(cache_dir, exist_ok=True)
  
                  if comm:
                      comm.barrier()
                      # Check whether cache directory needs to be created on each node.
                      if (
                          comm.local_rank == 0
                          and comm.rank != 0
                          and not os.path.exists(cache_dir)
                      ):
                          os.makedirs(cache_dir, exist_ok=True)
                          create_cache_flag = True
  
                  if create_cache_flag:
                      log_uri = (
                          uri.split("/", 3)[-1]
                          if uri.startswith("s3")
                          else uri
                      )
                      if comm:
                          logger.log(
                              99,
                              f'Creating cache data for "{log_uri}" on node rank:{comm.rank} local_rank:{comm.local_rank}',
                          )
                      else:
                          logger.log(
                              99, f'Creating cache data for "{log_uri}"'
                          )
                      if os.path.exists(uri):
                          cc = CreateCache(
                              uri, rng=rng, shuffle=shuffle
                          )
                          cc.create(cache_dir, normalize=False)
                      else:
                          with data_iterator_csv_dataset(
                              uri,
                              batch_size,
                              shuffle,
                              rng=rng,
                              normalize=False,
                              cache_dir=cache_dir,
                              with_memory_cache=False,
                          ) as di:
                              pass
                  if comm:
                      comm.barrier()
  
              rng = numpy.random.RandomState(dataset_index)
              dataset.data_iterator = lambda: data_iterator_cache(
                  cache_dir,
                  batch_size,
                  shuffle,
                  rng=rng,
                  normalize=dataset.normalize,
                  with_memory_cache=use_memory_cache,
              )
          elif (
              not cache_dir
              or overwrite_cache
              or not os.path.exists(cache_dir)
              or len(os.listdir(cache_dir)) == 0
          ):
              if comm:
                  logger.critical(
                      "Implicit cache creation does not support with MPI"
                  )
                  import sys
  
                  sys.exit(-1)
              else:
                  if cache_dir:
                      try:
                          os.makedirs(cache_dir)
                      except OSError:
                          pass  # python2 does not support exists_ok arg
                  dataset.data_iterator = (
                      lambda: data_iterator_csv_dataset(
                          uri,
                          batch_size,
                          shuffle,
                          rng=rng,
                          normalize=dataset.normalize,
                          cache_dir=cache_dir,
                      )
                  )
          else:
              dataset.data_iterator = lambda: data_iterator_cache(
                  cache_dir,
                  batch_size,
                  shuffle,
                  rng=rng,
                  normalize=dataset.normalize,
                  with_memory_cache=use_memory_cache,
              )
      else:
          dataset.data_iterator = None
      return dataset
  
imports: import itertools
  import os
  import re
  from collections import OrderedDict
  import nnabla
  import nnabla.functions
  import nnabla.solver
  import numpy
  from nnabla.core.graph_optimizer import IdentityRemover
  from nnabla.initializer import NormalInitializer, UniformInitializer, ConstantInitializer, RangeInitializer
  from nnabla.logger import logger
  from nnabla.utils import nnabla_pb2
  from nnabla.utils.communicator_util import current_communicator, single_or_rankzero
  from nnabla.utils.create_cache import CreateCache
  from nnabla.utils.data_iterator import data_iterator_csv_dataset, data_iterator_cache
  from nnabla.utils.get_file_handle import get_initial_file_loader, load_files
  from nnabla.utils.learning_rate_scheduler import PolynomialScheduler, CosineScheduler, ExponentialScheduler, StepScheduler, LinearWarmupScheduler
label_desc: Use image node_id 9 for calling a global function with example usage: _create_dataset(uri, batch_size, shuffle, no_image_normalization, cache_dir, overwrite_cache, create_cache_explicitly, prepare_data_iterator, dataset_index) and returns: dataset