docstr: Args:
      model:
      use_test_acc:
      epoch_num: how many epoch, set by scheduler
      train_loader:
      val_loader:
      test_loader:
      args:
  Returns:
docstr_tok: ["Args",":","model",":","use_test_acc",":","epoch_num",":","how","many","epoch",",","set","by","scheduler","train_loader",":","val_loader",":","test_loader",":","args",":","Returns",":"]
code: def fully_train_arch(
      cls,
      model,
      use_test_acc: bool,
      epoch_num,
      train_loader: DataLoader,
      val_loader: DataLoader,
      test_loader: DataLoader,
      args,
      logger=None,
  ) -> (float, float, dict):
      """
      Args:
          model:
          use_test_acc:
          epoch_num: how many epoch, set by scheduler
          train_loader:
          val_loader:
          test_loader:
          args:
      Returns:
      """
  
      if logger is None:
          from src.logger import logger
  
          logger = logger
  
      start_time, best_valid_auc = time.time(), 0.0
  
      num_labels = args.num_labels
      lr = args.lr
      iter_per_epoch = args.iter_per_epoch
      # report_freq = args.report_freq
      # given_patience = args.patience
  
      # assign new values
      args.epoch_num = epoch_num
  
      # for multiple classification
  
      # optimizer
      precision = "float32"
      mssgd = MSSGD(
          lr=args.lr,
          momentum=0.9,
          weight_decay=1e-4,
          dtype=singa_dtype[precision],
      )
      device_id = 0
      max_epoch = epoch_num
      graph = True
      verbosity = 0
      dist_option = "plain"
      spars = None
      global_rank = 0
      world_size = 1
  
      # training params
      if args.device == "cpu":
          dev = singa_device.get_default_device()
      else:  # GPU
          dev = singa_device.create_cuda_gpu_on(
              args.local_rank
          )  # need to change to CPU device for CPU-only machines
      dev.SetRandSeed(0)
  
      # For distributed training, sequential has better performance
      if hasattr(mssgd, "communicator"):
          DIST = True
          sequential = True
      else:
          DIST = False
          sequential = False
  
      info_dic = {}
      valid_auc = -1
      valid_loss = 0
  
      ### singa data
      tx = tensor.Tensor(
          (args.batch_size, args.nfeat), dev, singa_dtype[precision]
      )
      ty = tensor.Tensor((args.batch_size,), dev, tensor.int32)
      ### singa data
  
      model.set_optimizer(mssgd)
      model.compile(
          [tx], is_train=True, use_graph=graph, sequential=sequential
      )
      dev.SetVerbosity(verbosity)
  
      # Training and evaluation loop
      for epoch in range(max_epoch):
          start_time = time.time()
          logger.info(f"Epoch [{epoch:3d}/{epoch_num:3d}]")
          # np.random.shuffle(idx)
  
          if global_rank == 0:
              print("Starting Epoch %d:" % (epoch))
  
          # Training phase
          train_correct = np.zeros(shape=[1], dtype=np.float32)
          test_correct = np.zeros(shape=[1], dtype=np.float32)
          train_loss = np.zeros(shape=[1], dtype=np.float32)
  
          model.train()
          # print ("num_train_batch: \n", num_train_batch)
          # print ()
          batch_idx = 0
          # for b in range(num_train_batch):
          for batch_idx, batch in enumerate(train_loader):
              if batch_idx % 50 == 0:
                  print("trainer.py train batch_idx: \n", batch_idx)
              # Generate the batch data in this iteration
              # x = train_x[idx[b * batch_size:(b + 1) * batch_size]]
              # if model.dimension == 4:
              #     x = augmentation(x, batch_size)
              #     if (image_size != model.input_size):
              #         x = resize_dataset(x, model.input_size)
              # x = x.astype(np_dtype[precision])
              # y = train_y[idx[b * batch_size:(b + 1) * batch_size]]
  
              y = batch["y"].cpu().numpy()
              batch["id"] = batch["id"].cpu().numpy().astype(int)
              # batch['value'] = batch['value'].to(args.device)
              x = np.zeros(
                  (batch["id"].shape[0], args.nfeat), dtype=np.float32
              )
              # print ("target shape: ", target.shape)
              # print ("target: ", target)
              # print ("batch['id'] shape: ", batch['id'].shape)
              # print ("batch['id']: ", batch['id'])
              # print ("batch['value'] shape: ", batch['value'].shape)
              # print ("batch['value']: ", batch['value'])
              # print ("batch['id'].cpu().numpy().astype(int): \n", batch['id'].cpu().numpy().astype(int))
              for i in range(batch["id"].shape[0]):
                  x[i][batch["id"][i]] = (np.float32)(1.0)
              x = x.astype(dtype=np.float32)
              y = y.astype(dtype=np.int32)
  
              if (
                  x.shape[0] != args.batch_size
              ):  # last batch not processing
                  continue
  
              synflow_flag = False
              # Train the model
              # if True: # normal train steps
              # Copy the patch data into input tensors
              # print ("normal train steps\n")
              # print ("x.astype(np.float32): \n", x.astype(np.float32))
              # print ("y: \n", y)
              tx = tensor.Tensor(x.shape, dev, singa_dtype[precision])
              ty = tensor.Tensor((y.shape[0],), dev, tensor.int32)
              tx.copy_from_numpy(x)  # dtype=np.float32
              # print ("tx: \n", tx)
              ty.copy_from_numpy(y)
              # print ("ty: \n", ty)
              # print ("normal before model(tx, ty, synflow_flag, dist_option, spars)")
              # print ("train_cnn tx: \n", tx)
              # print ("train_cnn ty: \n", ty)
              # print ("trainer.py train before model forward ...")
              # print ("model: ", model)
              pn_p_g_list, out, loss = model(
                  tx, ty, dist_option, spars, synflow_flag
              )
              # print ("trainer.py train normal after model(tx, ty, synflow_flag, dist_option, spars)")
              # print ("trainer.py train tx shape: ", tx.shape)
              # print ("trainer.py train ty shape: ", ty.shape)
              # print ("trainer.py train out.shape: ", out.shape)
              # print ("trainer.py train out: ", out)
              # print ("trainer.py train y shape: ", y.shape)
              train_correct += accuracy(tensor.to_numpy(out), y)
              train_loss += tensor.to_numpy(loss)[0]
  
          if DIST:
              # Reduce the evaluation accuracy and loss from multiple devices
              reducer = tensor.Tensor((1,), dev, tensor.float32)
              train_correct = reduce_variable(
                  train_correct, mssgd, reducer
              )
              train_loss = reduce_variable(train_loss, mssgd, reducer)
  
          if global_rank == 0:
              print(
                  "Training loss = %f, training accuracy = %f"
                  % (
                      train_loss,
                      train_correct
                      / (batch_idx * args.batch_size * world_size),
                  ),
                  flush=True,
              )
              print("train total batch_idx: ", batch_idx)
              train_metric = train_correct / (
                  batch_idx * args.batch_size * world_size
              )
  
          # Evaluation phase
          model.eval()
          batch_idx = 0
          # for b in range(num_val_batch):
          # print ("evaluation begins")
          for batch_idx, batch in enumerate(test_loader):
              # print ("trainer.py test batch_idx: \n", batch_idx)
              # x = val_x[b * batch_size:(b + 1) * batch_size]
              # if model.dimension == 4:
              #     if (image_size != model.input_size):
              #         x = resize_dataset(x, model.input_size)
              # x = x.astype(np_dtype[precision])
              # y = val_y[b * batch_size:(b + 1) * batch_size]
              # batch['value'] = batch['value'].cpu().numpy().astype(np_dtype[precision])
              # x = batch['value'].cpu().numpy().astype(np_dtype[precision])
  
              y = batch["y"].cpu().numpy()
              batch["id"] = batch["id"].cpu().numpy().astype(int)
              # batch['value'] = batch['value'].to(args.device)
              x = np.zeros(
                  (batch["id"].shape[0], args.nfeat), dtype=np.float32
              )
              # print ("target shape: ", target.shape)
              # print ("target: ", target)
              # print ("batch['id'] shape: ", batch['id'].shape)
              # print ("batch['id']: ", batch['id'])
              # print ("batch['value'] shape: ", batch['value'].shape)
              # print ("batch['value']: ", batch['value'])
              # print ("batch['id'].cpu().numpy().astype(int): \n", batch['id'].cpu().numpy().astype(int))
              for i in range(batch["id"].shape[0]):
                  x[i][batch["id"][i]] = (np.float32)(1.0)
              # print ("x[1]: \n", x[1])
              x = x.astype(dtype=np.float32)
              y = y.astype(dtype=np.int32)
  
              if x.shape[0] != (
                  args.batch_size * 8
              ):  # last batch not processing
                  # print ("trainer.py test batch_idx: ", batch_idx)
                  # print ("trainer.py test x.shape: ", x.shape)
                  continue
  
              tx = tensor.Tensor(x.shape, dev, singa_dtype[precision])
              ty = tensor.Tensor((y.shape[0],), dev, tensor.int32)
              tx.copy_from_numpy(x)
              ty.copy_from_numpy(y)
              # print ("trainer.py test tx shape: ", tx.shape)
              out_test = model(tx)
              # print ("trainer.py test out_test shape: ", out_test.shape)
              # print ("trainer.py test y shape: ", y.shape)
              # print ("trainer.py out_test: ", out_test)
              # print ("trainer.py y: ", y)
              test_correct += accuracy(tensor.to_numpy(out_test), y)
              # print ("test_correct: ", test_correct)
  
          if DIST:
              # Reduce the evaulation accuracy from multiple devices
              test_correct = reduce_variable(
                  test_correct, mssgd, reducer
              )
  
          # Output the evaluation accuracy
          if global_rank == 0:
              print(
                  "Evaluation accuracy = %f, Elapsed Time = %fs"
                  % (
                      test_correct
                      / (batch_idx * args.batch_size * 8 * world_size),
                      time.time() - start_time,
                  ),
                  flush=True,
              )
              # print ("test all batch_idx: ", batch_idx)
              test_metric = test_correct / (
                  batch_idx * args.batch_size * 8 * world_size
              )
  
          info_dic[epoch] = {
              "train_metric": str(train_metric[0]),
              "test_metric": str(test_metric[0]),
              "train_loss": str(train_loss[0]),
              # "valid_loss": valid_loss,
              "train_test_total_time": str(time.time() - start_time),
          }
  
      dev.PrintTimeProfiling()
  
      # return valid_auc, time.time() - start_time, info_dic
      print("info_dic: ", info_dic)
      return test_metric, time.time() - start_time, info_dic
  
imports: import time
  from src.tools import utils
  from singa import singa_wrap
  from singa import device
  from singa import tensor
  from singa import opt
  from singa import autograd
  from singa.opt import Optimizer
  from singa.opt import DecayScheduler
  from singa.opt import Constant
  import numpy
  import time
  import argparse
  from PIL import Image
  from torch.utils.data import DataLoader
label_desc: Use image node_id 1 for calling the ModelTrainer obj's underlying member method code with example usage: obj.fully_train_arch(cls, model, use_test_acc, epoch_num, train_loader, val_loader, test_loader, args, logger) and returns: test_metric,  unknown,  info_dic