code: def main(args):
      """
      Main function.
      """
      host_name = socket.gethostname()
      print(f"{host_name}: Initializing DistDGL.")
      dgl.distributed.initialize(args.ip_config)
      print(f"{host_name}: Initializing PyTorch process group.")
      th.distributed.init_process_group(backend=args.backend)
      print(f"{host_name}: Initializing DistGraph.")
      g = dgl.distributed.DistGraph(
          args.graph_name, part_config=args.part_config
      )
      print(f"Rank of {host_name}: {g.rank()}")
  
      # Split train/val/test IDs for each trainer.
      pb = g.get_partition_book()
      if "trainer_id" in g.ndata:
          train_nid = dgl.distributed.node_split(
              g.ndata["train_mask"],
              pb,
              force_even=True,
              node_trainer_ids=g.ndata["trainer_id"],
          )
          val_nid = dgl.distributed.node_split(
              g.ndata["val_mask"],
              pb,
              force_even=True,
              node_trainer_ids=g.ndata["trainer_id"],
          )
          test_nid = dgl.distributed.node_split(
              g.ndata["test_mask"],
              pb,
              force_even=True,
              node_trainer_ids=g.ndata["trainer_id"],
          )
      else:
          train_nid = dgl.distributed.node_split(
              g.ndata["train_mask"], pb, force_even=True
          )
          val_nid = dgl.distributed.node_split(
              g.ndata["val_mask"], pb, force_even=True
          )
          test_nid = dgl.distributed.node_split(
              g.ndata["test_mask"], pb, force_even=True
          )
      local_nid = pb.partid2nids(pb.partid).detach().numpy()
      num_train_local = len(
          np.intersect1d(train_nid.numpy(), local_nid)
      )
      num_val_local = len(np.intersect1d(val_nid.numpy(), local_nid))
      num_test_local = len(np.intersect1d(test_nid.numpy(), local_nid))
      print(
          f"part {g.rank()}, train: {len(train_nid)} (local: {num_train_local}), "
          f"val: {len(val_nid)} (local: {num_val_local}), "
          f"test: {len(test_nid)} (local: {num_test_local})"
      )
      del local_nid
      if args.num_gpus == 0:
          device = th.device("cpu")
      else:
          dev_id = g.rank() % args.num_gpus
          device = th.device("cuda:" + str(dev_id))
      n_classes = args.n_classes
      if n_classes == 0:
          labels = g.ndata["labels"][np.arange(g.num_nodes())]
          n_classes = len(
              th.unique(labels[th.logical_not(th.isnan(labels))])
          )
          del labels
      print(f"Number of classes: {n_classes}")
  
      # Pack data.
      in_feats = g.ndata["features"].shape[1]
      data = train_nid, val_nid, test_nid, in_feats, n_classes, g
  
      # Train and evaluate.
      epoch_time, test_acc = run(args, device, data)
      print(
          f"Summary of node classification(GraphSAGE): GraphName "
          f"{args.graph_name} | TrainEpochTime(mean) {epoch_time:.4f} "
          f"| TestAccuracy {test_acc:.4f}"
      )
  
file_path: dgl/examples/distributed/graphsage/node_classification.py
imports: import argparse
  import socket
  import time
  import dgl
  import dgl.nn.pytorch
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  import torch.optim
  import tqdm
label_desc: Use image node_id 4 for calling a global function with example usage: main(args) without return types