code: def test_kv_multi_role():
      reset_envs()
      num_servers = 2
      num_trainers = 2
      num_samplers = 2
      generate_ip_config("kv_ip_mul_config.txt", 1, num_servers)
      # There are two trainer processes and each trainer process has two sampler processes.
      num_clients = num_trainers * (1 + num_samplers)
      ctx = mp.get_context("spawn")
      pserver_list = []
      pclient_list = []
      os.environ["DGL_NUM_SAMPLER"] = str(num_samplers)
      os.environ["DGL_NUM_SERVER"] = str(num_servers)
      for i in range(num_servers):
          pserver = ctx.Process(
              target=start_server_mul_role,
              args=(i, num_clients, num_servers),
          )
          pserver.start()
          pserver_list.append(pserver)
      for i in range(num_trainers):
          pclient = ctx.Process(target=start_client_mul_role, args=(i,))
          pclient.start()
          pclient_list.append(pclient)
      for i in range(num_trainers):
          pclient_list[i].join()
      for i in range(num_servers):
          pserver_list[i].join()
  
imports: import multiprocessing
  import os
  import socket
  import time
  import unittest
  import backend
  import dgl
  import numpy
  from dgl.graph_index import create_graph_index
  from numpy.testing import assert_array_equal
  from scipy import sparse
  from utils import generate_ip_config, reset_envs
label_desc: Use image node_id 10 for calling a global function with example usage: test_kv_multi_role() without return types