code: def build_knowledge_graph(
      num_nodes, num_rels, train, valid, test, reverse=True
  ):
      """Create a DGL Homogeneous graph with heterograph info stored as node or edge features."""
      src = []
      rel = []
      dst = []
      raw_subg = {}
      raw_subg_eset = {}
      raw_subg_etype = {}
      raw_reverse_sugb = {}
      raw_reverse_subg_eset = {}
      raw_reverse_subg_etype = {}
  
      # here there is noly one node type
      s_type = "node"
      d_type = "node"
  
      def add_edge(s, r, d, reverse, edge_set):
          r_type = str(r)
          e_type = (s_type, r_type, d_type)
          if raw_subg.get(e_type, None) is None:
              raw_subg[e_type] = ([], [])
              raw_subg_eset[e_type] = []
              raw_subg_etype[e_type] = []
          raw_subg[e_type][0].append(s)
          raw_subg[e_type][1].append(d)
          raw_subg_eset[e_type].append(edge_set)
          raw_subg_etype[e_type].append(r)
  
          if reverse is True:
              r_type = str(r + num_rels)
              re_type = (d_type, r_type, s_type)
              if raw_reverse_sugb.get(re_type, None) is None:
                  raw_reverse_sugb[re_type] = ([], [])
                  raw_reverse_subg_etype[re_type] = []
                  raw_reverse_subg_eset[re_type] = []
              raw_reverse_sugb[re_type][0].append(d)
              raw_reverse_sugb[re_type][1].append(s)
              raw_reverse_subg_eset[re_type].append(edge_set)
              raw_reverse_subg_etype[re_type].append(r + num_rels)
  
      for edge in train:
          s, r, d = edge
          assert r < num_rels
          add_edge(s, r, d, reverse, 1)  # train set
  
      for edge in valid:
          s, r, d = edge
          assert r < num_rels
          add_edge(s, r, d, reverse, 2)  # valid set
  
      for edge in test:
          s, r, d = edge
          assert r < num_rels
          add_edge(s, r, d, reverse, 3)  # test set
  
      subg = []
      fg_s = []
      fg_d = []
      fg_etype = []
      fg_settype = []
      for e_type, val in raw_subg.items():
          s, d = val
          s = np.asarray(s)
          d = np.asarray(d)
          etype = raw_subg_etype[e_type]
          etype = np.asarray(etype)
          settype = raw_subg_eset[e_type]
          settype = np.asarray(settype)
  
          fg_s.append(s)
          fg_d.append(d)
          fg_etype.append(etype)
          fg_settype.append(settype)
  
      settype = np.concatenate(fg_settype)
      if reverse is True:
          settype = np.concatenate(
              [settype, np.full((settype.shape[0]), 0)]
          )
      train_edge_mask = generate_mask_tensor(settype == 1)
      valid_edge_mask = generate_mask_tensor(settype == 2)
      test_edge_mask = generate_mask_tensor(settype == 3)
  
      for e_type, val in raw_reverse_sugb.items():
          s, d = val
          s = np.asarray(s)
          d = np.asarray(d)
          etype = raw_reverse_subg_etype[e_type]
          etype = np.asarray(etype)
          settype = raw_reverse_subg_eset[e_type]
          settype = np.asarray(settype)
  
          fg_s.append(s)
          fg_d.append(d)
          fg_etype.append(etype)
          fg_settype.append(settype)
  
      s = np.concatenate(fg_s)
      d = np.concatenate(fg_d)
      g = dgl_graph((s, d), num_nodes=num_nodes)
      etype = np.concatenate(fg_etype)
      settype = np.concatenate(fg_settype)
      etype = F.tensor(etype, dtype=F.data_type_dict["int64"])
      train_edge_mask = train_edge_mask
      valid_edge_mask = valid_edge_mask
      test_edge_mask = test_edge_mask
      train_mask = (
          generate_mask_tensor(settype == 1)
          if reverse is True
          else train_edge_mask
      )
      valid_mask = (
          generate_mask_tensor(settype == 2)
          if reverse is True
          else valid_edge_mask
      )
      test_mask = (
          generate_mask_tensor(settype == 3)
          if reverse is True
          else test_edge_mask
      )
      ntype = F.full_1d(
          num_nodes, 0, dtype=F.data_type_dict["int64"], ctx=F.cpu()
      )
  
      return g, (
          etype,
          ntype,
          train_edge_mask,
          valid_edge_mask,
          test_edge_mask,
          train_mask,
          valid_mask,
          test_mask,
      )
  
imports: from __future__ import absolute_import
  import os, sys
  import pickle
  import networkx
  import numpy
  import scipy.sparse
  from ..None import backend
  from ..convert import graph
  from ..utils import retry_method_with_fix
  from .dgl_dataset import DGLBuiltinDataset
  from .utils import _get_dgl_url, deprecate_function, deprecate_property, download, extract_archive, generate_mask_tensor, get_download_dir, load_graphs, load_info, makedirs, save_graphs, save_info
label_desc: Use image node_id 4 for calling a global function with example usage: build_knowledge_graph(num_nodes, num_rels, train, valid, test, reverse) and returns: g,  etype,  ntype,  train_edge_mask,  valid_edge_mask,  test_edge_mask,  train_mask,  valid_mask,  test_mask