code: def run(
      global_rank,
      world_size,
      local_rank,
      layer_hidden_list,
      max_epoch,
      batch_size,
      model,
      data,
      mssgd,
      graph,
      verbosity,
      dist_option="plain",
      spars=None,
      precision="float32",
  ):
      # dev = device.create_cuda_gpu_on(local_rank)  # need to change to CPU device for CPU-only machines
      dev = device.get_default_device()
      dev.SetRandSeed(0)
      np.random.seed(0)
  
      if data == "cifar10":
          from data import cifar10
  
          train_x, train_y, val_x, val_y = cifar10.load()
      elif data == "cifar100":
          from data import cifar100
  
          train_x, train_y, val_x, val_y = cifar100.load()
      elif data == "mnist":
          from data import mnist
  
          train_x, train_y, val_x, val_y = mnist.load()
  
      num_channels = train_x.shape[1]
      image_size = train_x.shape[2]
      data_size = np.prod(train_x.shape[1 : train_x.ndim]).item()
      num_classes = (np.max(train_y) + 1).item()
  
      if model == "resnet":
          from model import resnet
  
          model = resnet.resnet50(
              num_channels=num_channels, num_classes=num_classes
          )
      elif model == "xceptionnet":
          from model import xceptionnet
  
          model = xceptionnet.create_model(
              num_channels=num_channels, num_classes=num_classes
          )
      elif model == "cnn":
          from model import cnn
  
          model = cnn.create_model(
              num_channels=num_channels, num_classes=num_classes
          )
      elif model == "alexnet":
          from model import alexnet
  
          model = alexnet.create_model(
              num_channels=num_channels, num_classes=num_classes
          )
      elif model == "mlp":
          import os, sys, inspect
  
          current = os.path.dirname(
              os.path.abspath(inspect.getfile(inspect.currentframe()))
          )
          parent = os.path.dirname(current)
          sys.path.insert(0, parent)
          from mlp import model
  
          model = model.create_model(
              data_size=data_size, num_classes=num_classes
          )
  
      elif model == "msmlp":
          import os, sys, inspect
  
          current = os.path.dirname(
              os.path.abspath(inspect.getfile(inspect.currentframe()))
          )
          parent = os.path.dirname(current)
          sys.path.insert(0, parent)
          from msmlp import model
  
          model = model.create_model(
              data_size=data_size, num_classes=num_classes
          )
  
      elif model == "ms_model_mlp":
          import os, sys, inspect
  
          current = os.path.dirname(
              os.path.abspath(inspect.getfile(inspect.currentframe()))
          )
          parent = os.path.dirname(current)
          sys.path.insert(0, parent)
          from ms_model_mlp import model
  
          model = model.create_model(
              data_size=data_size,
              num_classes=num_classes,
              layer_hidden_list=layer_hidden_list,
          )
      # print ("model: \n", model)
  
      # For distributed training, sequential has better performance
      if hasattr(mssgd, "communicator"):
          DIST = True
          sequential = True
      else:
          DIST = False
          sequential = False
  
      if DIST:
          train_x, train_y, val_x, val_y = partition(
              global_rank, world_size, train_x, train_y, val_x, val_y
          )
  
      if model.dimension == 4:
          tx = tensor.Tensor(
              (
                  batch_size,
                  num_channels,
                  model.input_size,
                  model.input_size,
              ),
              dev,
              singa_dtype[precision],
          )
      elif model.dimension == 2:
          tx = tensor.Tensor(
              (batch_size, data_size), dev, singa_dtype[precision]
          )
          np.reshape(train_x, (train_x.shape[0], -1))
          np.reshape(val_x, (val_x.shape[0], -1))
  
      ty = tensor.Tensor((batch_size,), dev, tensor.int32)
      num_train_batch = train_x.shape[0] // batch_size
      num_val_batch = val_x.shape[0] // batch_size
      idx = np.arange(train_x.shape[0], dtype=np.int32)
  
      # Attach model to graph
      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()
          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()
          for b in range(num_train_batch):
              # if b % 200 == 0:
              #     print ("b: \n", b)
              # Generate the patch 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]]
  
              synflow_flag = False
              # Train the model
              if epoch == (max_epoch - 1) and b == (
                  num_train_batch - 1
              ):  ### synflow calcuation for the last batch
                  print("last epoch calculate synflow")
                  synflow_flag = True
                  ### step 1: all one input
                  # Copy the patch data into input tensors
                  tx.copy_from_numpy(np.ones(x.shape, dtype=np.float32))
                  ty.copy_from_numpy(y)
                  ### step 2: all weights turned to positive (done)
                  ### step 3: new loss (done)
                  # print ("before model forward ...")
                  pn_p_g_list, out, loss = model(
                      tx, ty, dist_option, spars, synflow_flag
                  )
                  ### step 4: calculate the multiplication of weights
                  synflow_score = 0.0
                  for pn_p_g_item in pn_p_g_list:
                      print(
                          "calculate weight param * grad parameter name: \n",
                          pn_p_g_item[0],
                      )
                      if (
                          len(pn_p_g_item[1].shape) == 2
                      ):  # param_value.data is "weight"
                          print(
                              "pn_p_g_item[1].shape: \n",
                              pn_p_g_item[1].shape,
                          )
                          synflow_score += np.sum(
                              np.absolute(
                                  tensor.to_numpy(pn_p_g_item[1])
                                  * tensor.to_numpy(pn_p_g_item[2])
                              )
                          )
                  print("layer_hidden_list: \n", layer_hidden_list)
                  print("synflow_score: \n", synflow_score)
              elif epoch == (max_epoch - 1) and b == (
                  num_train_batch - 2
              ):  # all weights turned to positive
                  # Copy the patch data into input tensors
                  tx.copy_from_numpy(x)
                  ty.copy_from_numpy(y)
                  # print ("before model forward ...")
                  pn_p_g_list, out, loss = model(
                      tx, ty, dist_option, spars, synflow_flag
                  )
                  train_correct += accuracy(tensor.to_numpy(out), y)
                  train_loss += tensor.to_numpy(loss)[0]
                  # all params turned to positive
                  for pn_p_g_item in pn_p_g_list:
                      print(
                          "absolute value parameter name: \n",
                          pn_p_g_item[0],
                      )
                      pn_p_g_item[1] = tensor.abs(
                          pn_p_g_item[1]
                      )  # tensor actually ...
              else:  # normal train steps
                  # Copy the patch data into input tensors
                  tx.copy_from_numpy(x)
                  ty.copy_from_numpy(y)
                  # print ("normal before model(tx, ty, synflow_flag, dist_option, spars)")
                  # print ("train_cnn tx: \n", tx)
                  # print ("train_cnn ty: \n", ty)
                  # print ("before model forward ...")
                  pn_p_g_list, out, loss = model(
                      tx, ty, dist_option, spars, synflow_flag
                  )
                  # print ("normal after model(tx, ty, synflow_flag, dist_option, spars)")
                  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
                      / (num_train_batch * batch_size * world_size),
                  ),
                  flush=True,
              )
  
          # Evaluation phase
          model.eval()
          for b in range(num_val_batch):
              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]
              tx.copy_from_numpy(x)
              ty.copy_from_numpy(y)
              out_test = model(tx)
              test_correct += accuracy(tensor.to_numpy(out_test), y)
  
          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
                      / (num_val_batch * batch_size * world_size),
                      time.time() - start_time,
                  ),
                  flush=True,
              )
  
      dev.PrintTimeProfiling()
  
imports: 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
label_desc: Use image node_id 6 for calling a global function with example usage: run(global_rank, world_size, local_rank, layer_hidden_list, max_epoch, batch_size, model, data, mssgd, graph, verbosity, dist_option, spars, precision) without return types