code: def train(model, predictor, data, split_edge, optimizer, batch_size):
      model.train()
      predictor.train()
  
      source_edge = split_edge["train"]["source_node"].to(data.x.device)
      target_edge = split_edge["train"]["target_node"].to(data.x.device)
  
      total_loss = total_examples = 0
      for perm in DataLoader(
          range(source_edge.size(0)), batch_size, shuffle=True
      ):
          optimizer.zero_grad()
  
          h = model(data.x, data.adj_t)
  
          src, dst = source_edge[perm], target_edge[perm]
  
          pos_out = predictor(h[src], h[dst])
          pos_loss = -torch.log(pos_out + 1e-15).mean()
  
          # Just do some trivial random sampling.
          dst_neg = torch.randint(
              0,
              data.num_nodes,
              src.size(),
              dtype=torch.long,
              device=h.device,
          )
          neg_out = predictor(h[src], h[dst_neg])
          neg_loss = -torch.log(1 - neg_out + 1e-15).mean()
  
          loss = pos_loss + neg_loss
          loss.backward()
          optimizer.step()
  
          num_examples = pos_out.size(0)
          total_loss += loss.item() * num_examples
          total_examples += num_examples
  
      return total_loss / total_examples
  
imports: import argparse
  import torch
  from torch.nn import Parameter
  import torch.nn.functional
  from torch.utils.data import DataLoader
  import torch_geometric.transforms
  from torch_geometric.nn import GCNConv, SAGEConv
  from ogb.linkproppred import PygLinkPropPredDataset, Evaluator
  from logger import Logger
label_desc: Use image node_id 1 for calling a global function with example usage: train(model, predictor, data, split_edge, optimizer, batch_size) and returns: unknown