code: def testCopyCPUto6GPUs(self):
      from tinygrad.runtime.ops_gpu import CLDevice
  
      if len(CLDevice.device_ids) != 6:
          raise unittest.SkipTest("computer doesn't have 6 GPUs")
      t = Tensor.rand(N, N, device="cpu").realize()
      print(f"buffer: {t.nbytes()*1e-9:.2f} GB")
      for _ in range(3):
          with Timing(
              "sync:  ",
              on_exit=lambda ns: f" @ {t.nbytes()/ns:.2f} GB/s ({t.nbytes()*6/ns:.2f} GB/s total)",
          ):
              with Timing("queue: "):
                  for g in range(6):
                      t.to(f"gpu:{g}").realize()
              Device["gpu"].synchronize()
  
file_path: tinygrad/test/test_copy_speed.py
imports: import unittest
  from tinygrad import Tensor
  from tinygrad import Device
  from tinygrad.helpers import Timing, CI, OSX
  import multiprocessing.shared_memory
label_desc: Use image node_id 6 for calling the TestCopySpeed obj's underlying member method code with example usage: obj.testCopyCPUto6GPUs() without return types