code: def read_to_gpu_pingpong(fd, sz, gpubuf):
      psz = 256 * 1024 * 1024
      print(f"piece size {psz/(1024*1024):.2f} MB")
      with Timing("gpu host alloc: ", lambda x: f", {sz/x:.2f} GB/s"):
          hst1 = dev.allocator._hostalloc(psz)
          hst2 = dev.allocator._hostalloc(psz)
  
      os.lseek(fd, 0, os.SEEK_SET)
      with Timing("total: ", lambda x: f", {sz/x:.2f} GB/s"):
          for i in range(sz // (psz * 2)):
              with Timing(
                  "tfer(0):           ", lambda x: f", {psz/x:.2f} GB/s"
              ):
                  ret = libc.read(fd, hst1, psz)
                  dev.synchronize()
                  dev.allocator._copyin_async(gpubuf, hst1, psz)
              with Timing(
                  "tfer(1):           ", lambda x: f", {psz/x:.2f} GB/s"
              ):
                  ret = libc.read(fd, hst2, psz)
                  dev.synchronize()
                  dev.allocator._copyin_async(gpubuf, hst2, psz)
          dev.synchronize()
  
file_path: tinygrad/extra/disk_read_speed.py
imports: import os, ctypes, ctypes.util, io, mmap
  from tinygrad import Tensor, dtypes, Device
  from tinygrad.helpers import Timing, from_mv
  from tinygrad.runtime.ops_hip import HIPDevice
label_desc: Use image node_id 5 for calling a global function with example usage: read_to_gpu_pingpong(fd, sz, gpubuf) without return types