code: def init_process(
      process_rank: int,
      world_size: int,
      distributed_device_ids: List[int],
      func: Callable,
      func_args: Tuple = None,
      func_kwargs: Dict[str, Any] = None,
      primary_addr: str = "127.0.0.1",
      primary_port: int = 29500,
  ):
      assert world_size > 1
  
      global_rank = process_rank
  
      gpu_id = distributed_device_ids[process_rank]  # type: ignore
  
      if gpu_id >= 0:
          torch.cuda.set_device(int(gpu_id))
          dist.init_process_group(
              backend="nccl",
              init_method=f"tcp://{primary_addr}:{primary_port}",
              world_size=world_size,
              rank=global_rank,
          )
      else:
          dist.init_process_group(
              backend="gloo",
              init_method=f"tcp://{primary_addr}:{primary_port}",
              world_size=world_size,
              rank=global_rank,
              timeout=datetime.timedelta(seconds=120),
          )
  
      func(
          global_rank,
          world_size,
          gpu_id,
          *(func_args or []),
          **(func_kwargs or {}),
      )
  
      #  dist.barrier()
      dist.destroy_process_group()
  
imports: import datetime
  from typing import List, Dict, Any, Tuple, Callable
  import torch
  import torch.distributed
  import torch.multiprocessing
  from allennlp.common.checks import check_for_gpu
label_desc: Use image node_id 1 for calling a global function with example usage: init_process(process_rank, world_size, distributed_device_ids, func, func_args, func_kwargs, primary_addr, primary_port) without return types