code: def batch_load_resnet(batch_size=64, val=False, shuffle=True):
      from extra.datasets.imagenet import get_train_files, get_val_files
  
      files = get_val_files() if val else get_train_files()
      from extra.datasets.imagenet import get_imagenet_categories
  
      cir = get_imagenet_categories()
  
      BATCH_COUNT = 32
      # q_in, q_out = MyQueue(multiple_writers=False), MyQueue(multiple_readers=False)
      q_in, q_out = Queue(), Queue()
  
      sz = (batch_size * BATCH_COUNT, 224, 224, 3)
      shm = shared_memory.SharedMemory(
          name="resnet_X", create=True, size=prod(sz)
      )
      # disk:shm is slower
      # X = Tensor.empty(*sz, dtype=dtypes.uint8, device=f"disk:shm:{shm.name}")
      X = Tensor.empty(
          *sz, dtype=dtypes.uint8, device=f"disk:/dev/shm/resnet_X"
      )
      Y = [None] * (batch_size * BATCH_COUNT)
  
      procs = []
      for _ in range(64):
          p = Process(target=loader_process, args=(q_in, q_out, X))
          p.daemon = True
          p.start()
          procs.append(p)
  
      gen = (
          shuffled_indices(len(files))
          if shuffle
          else iter(range(len(files)))
      )
  
      def enqueue_batch(num):
          for idx in range(num * batch_size, (num + 1) * batch_size):
              fn = files[next(gen)]
              q_in.put((idx, fn))
              Y[idx] = cir[fn.split("/")[-2]]
  
      for bn in range(BATCH_COUNT):
          enqueue_batch(bn)
  
      class Cookie:
          def __init__(self, num):
              self.num = num
  
          def __del__(self):
              try:
                  enqueue_batch(self.num)
              except StopIteration:
                  pass
  
      gotten = [0] * BATCH_COUNT
  
      def receive_batch():
          while 1:
              num = q_out.get() // batch_size
              gotten[num] += 1
              if gotten[num] == batch_size:
                  break
          gotten[num] = 0
          return (
              X[num * batch_size : (num + 1) * batch_size],
              Y[num * batch_size : (num + 1) * batch_size],
              Cookie(num),
          )
  
      # NOTE: this is batch aligned, last ones are ignored
      for _ in range(0, len(files) // batch_size):
          yield receive_batch()
  
      # shutdown processes
      for _ in procs:
          q_in.put(None)
      for p in procs:
          p.join()
      shm.close()
      shm.unlink()
  
file_path: tinygrad/examples/mlperf/dataloader.py
imports: import random, time, ctypes, struct
  import numpy
  from PIL import Image
  from tqdm import tqdm
  import pickle
  from tinygrad import dtypes, Tensor
  from tinygrad.helpers import getenv, prod, Timing
  from multiprocessing import Queue, Process, shared_memory, connection, Lock
label_desc: Use image node_id 3 for calling a global function with example usage: batch_load_resnet(batch_size, val, shuffle) and returns: X,  Y,  Cookie