code: def track_time(data, dgl_sparse):
      # load graph data
      dataset = utils.process_data(data)
      args = config()
      devices = [0, 1, 2, 3]
      args.dgl_sparse = dgl_sparse
      args.dataset = dataset
      ogb_dataset = False
  
      if data == "am":
          args.n_bases = 40
          args.l2norm = 5e-4
      elif data == "ogbn-mag":
          args.n_bases = 2
          args.l2norm = 0
      else:
          raise ValueError()
  
      if ogb_dataset is True:
          split_idx = dataset.get_idx_split()
          train_idx = split_idx["train"]["paper"]
          val_idx = split_idx["valid"]["paper"]
          test_idx = split_idx["test"]["paper"]
          hg_orig, labels = dataset[0]
          subgs = {}
          for etype in hg_orig.canonical_etypes:
              u, v = hg_orig.all_edges(etype=etype)
              subgs[etype] = (u, v)
              subgs[(etype[2], "rev-" + etype[1], etype[0])] = (v, u)
          hg = dgl.heterograph(subgs)
          hg.nodes["paper"].data["feat"] = hg_orig.nodes["paper"].data[
              "feat"
          ]
          labels = labels["paper"].squeeze()
  
          num_rels = len(hg.canonical_etypes)
          num_of_ntype = len(hg.ntypes)
          num_classes = dataset.num_classes
          if args.dataset == "ogbn-mag":
              category = "paper"
          print("Number of relations: {}".format(num_rels))
          print("Number of class: {}".format(num_classes))
          print("Number of train: {}".format(len(train_idx)))
          print("Number of valid: {}".format(len(val_idx)))
          print("Number of test: {}".format(len(test_idx)))
  
      else:
          # Load from hetero-graph
          hg = dataset[0]
  
          num_rels = len(hg.canonical_etypes)
          num_of_ntype = len(hg.ntypes)
          category = dataset.predict_category
          num_classes = dataset.num_classes
          train_mask = hg.nodes[category].data.pop("train_mask")
          test_mask = hg.nodes[category].data.pop("test_mask")
          labels = hg.nodes[category].data.pop("labels")
          train_idx = th.nonzero(train_mask, as_tuple=False).squeeze()
          test_idx = th.nonzero(test_mask, as_tuple=False).squeeze()
  
          # AIFB, MUTAG, BGS and AM datasets do not provide validation set split.
          # Split train set into train and validation if args.validation is set
          # otherwise use train set as the validation set.
          if args.validation:
              val_idx = train_idx[: len(train_idx) // 5]
              train_idx = train_idx[len(train_idx) // 5 :]
          else:
              val_idx = train_idx
  
      node_feats = []
      for ntype in hg.ntypes:
          if len(hg.nodes[ntype].data) == 0 or args.node_feats is False:
              node_feats.append(hg.num_nodes(ntype))
          else:
              assert len(hg.nodes[ntype].data) == 1
              feat = hg.nodes[ntype].data.pop("feat")
              node_feats.append(feat.share_memory_())
  
      # get target category id
      category_id = len(hg.ntypes)
      for i, ntype in enumerate(hg.ntypes):
          if ntype == category:
              category_id = i
          print("{}:{}".format(i, ntype))
  
      g = dgl.to_homogeneous(hg)
      g.ndata["ntype"] = g.ndata[dgl.NTYPE]
      g.ndata["ntype"].share_memory_()
      g.edata["etype"] = g.edata[dgl.ETYPE]
      g.edata["etype"].share_memory_()
      g.ndata["type_id"] = g.ndata[dgl.NID]
      g.ndata["type_id"].share_memory_()
      node_ids = th.arange(g.num_nodes())
  
      # find out the target node ids
      node_tids = g.ndata[dgl.NTYPE]
      loc = node_tids == category_id
      target_idx = node_ids[loc]
      target_idx.share_memory_()
      train_idx.share_memory_()
      val_idx.share_memory_()
      test_idx.share_memory_()
      # Create csr/coo/csc formats before launching training processes with multi-gpu.
      # This avoids creating certain formats in each sub-process, which saves momory and CPU.
      g.create_formats_()
  
      n_gpus = len(devices)
      n_cpus = mp.cpu_count()
  
      ctx = mp.get_context("spawn")
      queue = ctx.Queue()
      procs = []
      num_train_seeds = train_idx.shape[0]
      num_valid_seeds = val_idx.shape[0]
      num_test_seeds = test_idx.shape[0]
      train_seeds = th.randperm(num_train_seeds)
      valid_seeds = th.randperm(num_valid_seeds)
      test_seeds = th.randperm(num_test_seeds)
      tseeds_per_proc = num_train_seeds // n_gpus
      vseeds_per_proc = num_valid_seeds // n_gpus
      tstseeds_per_proc = num_test_seeds // n_gpus
  
      for proc_id in range(n_gpus):
          # we have multi-gpu for training, evaluation and testing
          # so split trian set, valid set and test set into num-of-gpu parts.
          proc_train_seeds = train_seeds[
              proc_id
              * tseeds_per_proc : (proc_id + 1)
              * tseeds_per_proc
              if (proc_id + 1) * tseeds_per_proc < num_train_seeds
              else num_train_seeds
          ]
          proc_valid_seeds = valid_seeds[
              proc_id
              * vseeds_per_proc : (proc_id + 1)
              * vseeds_per_proc
              if (proc_id + 1) * vseeds_per_proc < num_valid_seeds
              else num_valid_seeds
          ]
          proc_test_seeds = test_seeds[
              proc_id
              * tstseeds_per_proc : (proc_id + 1)
              * tstseeds_per_proc
              if (proc_id + 1) * tstseeds_per_proc < num_test_seeds
              else num_test_seeds
          ]
  
          p = ctx.Process(
              target=run,
              args=(
                  proc_id,
                  n_gpus,
                  n_cpus // n_gpus,
                  args,
                  devices,
                  (
                      g,
                      node_feats,
                      num_of_ntype,
                      num_classes,
                      num_rels,
                      target_idx,
                      train_idx,
                      val_idx,
                      test_idx,
                      labels,
                  ),
                  (proc_train_seeds, proc_valid_seeds, proc_test_seeds),
                  queue,
              ),
          )
          p.start()
  
          procs.append(p)
      for p in procs:
          p.join()
      time_records = queue.get(block=False)
      num_exclude = 10  # exclude first 10 iterations
      if len(time_records) < 15:
          # exclude less if less records
          num_exclude = int(len(time_records) * 0.3)
      return np.mean(time_records[num_exclude:])
  
imports: import argparse
  import gc
  import logging
  import time
  from pathlib import Path
  from types import SimpleNamespace
  import dgl
  import numpy
  import torch
  import torch.multiprocessing
  import torch.nn
  import torch.nn.functional
  from dgl.nn import RelGraphConv
  from torch.multiprocessing import Queue
  from torch.nn.parallel import DistributedDataParallel
  from torch.utils.data import DataLoader
  from ..None import utils
label_desc: Use image node_id 3 for calling a global function with example usage: track_time(data, dgl_sparse) and returns: np