code: def main(opts):
      t1 = time.time()
  
      # Setup dataset and data loader
      if opts["dataset"] == "cycles":
          from cycles import (
              CycleDataset,
              CycleModelEvaluation,
              CyclePrinting,
          )
  
          dataset = CycleDataset(fname=opts["path_to_dataset"])
          evaluator = CycleModelEvaluation(
              v_min=opts["min_size"],
              v_max=opts["max_size"],
              dir=opts["log_dir"],
          )
          printer = CyclePrinting(
              num_epochs=opts["nepochs"],
              num_batches=opts["ds_size"] // opts["batch_size"],
          )
      else:
          raise ValueError(
              "Unsupported dataset: {}".format(opts["dataset"])
          )
  
      data_loader = DataLoader(
          dataset,
          batch_size=1,
          shuffle=True,
          num_workers=0,
          collate_fn=dataset.collate_single,
      )
  
      # Initialize_model
      model = DGMG(
          v_max=opts["max_size"],
          node_hidden_size=opts["node_hidden_size"],
          num_prop_rounds=opts["num_propagation_rounds"],
      )
  
      # Initialize optimizer
      if opts["optimizer"] == "Adam":
          optimizer = Adam(model.parameters(), lr=opts["lr"])
      else:
          raise ValueError("Unsupported argument for the optimizer")
  
      t2 = time.time()
  
      # Training
      model.train()
      for epoch in range(opts["nepochs"]):
          batch_count = 0
          batch_loss = 0
          batch_prob = 0
          optimizer.zero_grad()
  
          for i, data in enumerate(data_loader):
              log_prob = model(actions=data)
              prob = log_prob.detach().exp()
  
              loss = -log_prob / opts["batch_size"]
              prob_averaged = prob / opts["batch_size"]
  
              loss.backward()
  
              batch_loss += loss.item()
              batch_prob += prob_averaged.item()
              batch_count += 1
  
              if batch_count % opts["batch_size"] == 0:
                  printer.update(
                      epoch + 1,
                      {
                          "averaged_loss": batch_loss,
                          "averaged_prob": batch_prob,
                      },
                  )
  
                  if opts["clip_grad"]:
                      clip_grad_norm_(
                          model.parameters(), opts["clip_bound"]
                      )
  
                  optimizer.step()
  
                  batch_loss = 0
                  batch_prob = 0
                  optimizer.zero_grad()
  
      t3 = time.time()
  
      model.eval()
      evaluator.rollout_and_examine(
          model, opts["num_generated_samples"]
      )
      evaluator.write_summary()
  
      t4 = time.time()
  
      print(
          "It took {} to setup.".format(
              datetime.timedelta(seconds=t2 - t1)
          )
      )
      print(
          "It took {} to finish training.".format(
              datetime.timedelta(seconds=t3 - t2)
          )
      )
      print(
          "It took {} to finish evaluation.".format(
              datetime.timedelta(seconds=t4 - t3)
          )
      )
      print(
          "--------------------------------------------------------------------------"
      )
      print(
          "On average, an epoch takes {}.".format(
              datetime.timedelta(seconds=(t3 - t2) / opts["nepochs"])
          )
      )
  
      del model.g
      torch.save(model, "./model.pth")
  
file_path: dgl/examples/pytorch/dgmg/main.py
imports: import argparse
  import datetime
  import time
  import torch
  from model import DGMG
  from torch.nn.utils import clip_grad_norm_
  from torch.optim import Adam
  from torch.utils.data import DataLoader
label_desc: Use image node_id 1 for calling a global function with example usage: main(opts) without return types