code: def train_and_eval(
      model,
      config,
      train_loader,
      valid_loaders,
      test_loader,
      optimizer,
      scheduler,
  ):
      evaluator = PCQM4MEvaluator()
      if dist.get_rank() == 0:
          writer = SummaryWriter(config.log_dir)
  
      best_valid = 1000
      global_step = 0
      header = "%s\n" % config.task_name
      msg_list = []
      epoch_step = len(train_loader)
      topk_best = []
      topk_num = 5
      for i in range(topk_num):
          msg_list.append("")
          topk_best.append([0, 1000])
      for epoch in range(1, config.epochs + 1):
          model.train()
          #  if dist.get_rank() == 0:
          #  bn_summary(writer, model, epoch)
          loss_accum = 0
          train_mae = 1000
          for step, (batch_dict, labels, others) in enumerate(
              train_loader
          ):
              feed_dict = {}
              for key, value in batch_dict.items():
                  if "graph" in key:
                      feed_dict[key] = value.tensor()
                  else:
                      feed_dict[key] = paddle.to_tensor(value)
              labels = paddle.to_tensor(labels)
  
              pred = paddle.reshape(
                  model(feed_dict),
                  shape=[
                      -1,
                  ],
              )
              loss = reg_criterion(pred, labels)
              loss.backward()
              optimizer.step()
              optimizer.clear_grad()
  
              loss_accum += loss.numpy()
  
              if global_step % config.log_step == 0:
                  log.info(
                      "Epoch: %s | Step: %s/%s | Train loss: %.6f"
                      % (
                          epoch,
                          step,
                          epoch_step,
                          loss_accum / (step + 1),
                      )
                  )
              global_step += 1
  
          train_mae = loss_accum / (step + 1)
          dist.barrier()
  
          if dist.get_rank() == 0 and config.to_valid_step < epoch:
              valid_dict = evaluate(
                  model, valid_loaders["valid"], config
              )
              valid_mae = evaluator.eval(valid_dict)["mae"]
  
              writer.add_scalar("train/mae", train_mae, epoch)
              writer.add_scalar("valid/mae", valid_mae, epoch)
  
              if config.split_mode is not None:
                  left_dict = evaluate(
                      model, valid_loaders["left"], config, "left_valid"
                  )
                  left_valid_mae = evaluator.eval(left_dict)["mae"]
                  writer.add_scalar("valid/left", left_valid_mae, epoch)
  
              if valid_mae < topk_best[topk_num - 1][1]:
                  best_valid = valid_mae
  
                  output_dir = os.path.join(
                      config.output_dir, "%03d" % epoch
                  )
                  make_dir(output_dir)
                  save_pred_result(output_dir, "crossvalid", valid_dict)
                  if config.split_mode is not None:
                      save_pred_result(
                          output_dir, "leftvalid", left_dict
                      )
  
                  # if valid is best, save test result
                  test_dict = evaluate(
                      model, test_loader, config, mode="test"
                  )
                  save_pred_result(output_dir, "test", test_dict)
  
                  save_dir = os.path.join(
                      config.save_dir, "%03d" % epoch
                  )
                  make_dir(save_dir)
                  ckpt_file = os.path.join(
                      save_dir, "checkpoint.pdparams"
                  )
                  log.info("saving model checkpoints in %s" % ckpt_file)
                  paddle.save(model.state_dict(), ckpt_file)
                  #  optim_file = os.path.join(config.save_dir, "optimizer.pdparams")
                  #  log.info("saving optimizer checkpoints in %s" % optim_file)
                  #  paddle.save(optimizer.state_dict(), optim_file)
  
                  # calculate top n
                  for i in range(topk_num):
                      if valid_mae < topk_best[i][1]:
                          topk_best.insert(i, [epoch, valid_mae])
                          k_idx = i
                          break
                  to_rm = topk_best[-1]
  
                  tmp_output_dir = os.path.join(
                      config.output_dir, "%03d" % to_rm[0]
                  )
                  tmp_save_dir = os.path.join(
                      config.save_dir, "%03d" % to_rm[0]
                  )
                  try:
                      shutil.rmtree(tmp_output_dir)
                      shutil.rmtree(tmp_save_dir)
                  except OSError:
                      pass
  
                  topk_best = topk_best[:-1]
                  with open(
                      os.path.join(config.output_dir, "ckpt_info"), "w"
                  ) as f:
                      for item in topk_best:
                          f.write("%s\n" % item)
  
              v_lr = (
                  0.0
                  if config.lr_mode == "Reduce"
                  else scheduler.get_lr()
              )
              info = (
                  "Epoch: %s | lr: %s | Train: %.6f | Valid: %.6f | Best Valid: %.6f"
                  % (epoch, v_lr, train_mae, valid_mae, topk_best[0][1])
              )
              log.info(info)
  
              writer.add_scalar("valid/best", topk_best[0][1], epoch)
  
          if isinstance(scheduler, float):
              pass
          elif config.lr_mode == "Reduce":
              if dist.get_rank() == 0:
                  valid_mae = paddle.to_tensor(
                      valid_mae, dtype="float32"
                  )
              else:
                  valid_mae = paddle.to_tensor(0.0, dtype="float32")
              paddle.distributed.broadcast(valid_mae, 0)
              scheduler.step(valid_mae)
          else:
              scheduler.step()
  
imports: import os
  import sys
  import time
  import shutil
  import random
  import argparse
  import numpy
  from tqdm import tqdm
  from functools import reduce
  from datetime import datetime
  from tensorboardX import SummaryWriter
  import paddle
  import paddle.nn
  import paddle.nn.functional
  import paddle.distributed
  import pgl
  from pgl.utils.data import Dataloader
  from pgl.utils.logger import log
  from ogb.lsc import PCQM4MEvaluator
  from ogb.utils import smiles2graph
  from utils.config import prepare_config, make_dir
  from utils.logger import prepare_logger, log_to_file
  import model
  import dataset
label_desc: Use image node_id 8 for calling a global function with example usage: train_and_eval(model, config, train_loader, valid_loaders, test_loader, optimizer, scheduler) without return types