class_docstr: Create a ring of nodes (processes). Each node runs a copy of the same
  function.
  
  :param processes: Number of ring nodes in this Ring.
  :param func: the target function that each ring node will run.
  :param initializer: the initialization function that each ring node runs.
      This is used to setup the custom ring structure like PyTorch's
      torch.distributed, Horovod, etc.
  :param initargs: positional arguments that are passed to initializer.
      Currently this is not used.
class_docstr_tok: ["Create","a","ring","of","nodes","(","processes",")",".","Each","node","runs","a","copy","of","the","same","function",".",":","param","processes",":","Number","of","ring","nodes","in","this","Ring",".",":","param","func",":","the","target","function","that","each","ring","node","will","run",".",":","param","initializer",":","the","initialization","function","that","each","ring","node","runs",".","This","is","used","to","setup","the","custom","ring","structure","like","PyTorch's","torch.distributed",",","Horovod",",","etc",".",":","param","initargs",":","positional","arguments","that","are","passed","to","initializer",".","Currently","this","is","not","used","."]
code: def _target(self):
      rank = self.rank
      node = self.members[rank]
  
      backend = get_backend()
      ip, _, _ = backend.get_listen_addr()
      port = random.randint(30000, 50000)
  
      node.connected = True
      node.ip = ip
      node.port = port
      self.members[rank] = node
  
      self.initializer(self)
      self.func(rank, self.size)
  
file_path: fiber/fiber/experimental/ring.py
imports: import multiprocessing
  import random
  import fiber
  from fiber.backend import get_backend
label_desc: Use image node_id 2 for calling the Ring obj's underlying member method code with example usage: obj._target() without return types