code: import math
  import time
  import random
  import numpy as np
  import torch
  import torch.optim as optim
  import torch.optim.lr_scheduler as lrs
  
  
  def set_seed(seed):
      random.seed(seed)
      np.random.seed(seed)
      torch.manual_seed(seed)
      if torch.cuda.device_count() == 1:
          torch.cuda.manual_seed(seed)
      else:
          torch.cuda.manual_seed_all(seed)
      
  
  class timer():
      def __init__(self):
          self.acc = 0
          self.tic()
  
      def tic(self):
          self.t0 = time.time()
  
      def toc(self):
          return time.time() - self.t0
  
      def hold(self):
          self.acc += self.toc()
  
      def release(self):
          ret = self.acc
          self.acc = 0
  
          return ret
  
      def reset(self):
          self.acc = 0
  
  
  def quantize(img, rgb_range):
      pixel_range = 255 / rgb_range
      return img.mul(pixel_range).clamp(0, 255).round().div(pixel_range)
  
  
  def calc_psnr(sr, hr, scale, rgb_range, benchmark=False):
      if sr.size(-2) > hr.size(-2) or sr.size(-1) > hr.size(-1):
          print("the dimention of sr image is not equal to hr's! ")
          sr = sr[:,:,:hr.size(-2),:hr.size(-1)]
      diff = (sr - hr).data.div(rgb_range)
  
      if benchmark:
          shave = scale
          if diff.size(1) > 1:
              convert = diff.new(1, 3, 1, 1)
              convert[0, 0, 0, 0] = 65.738
              convert[0, 1, 0, 0] = 129.057
              convert[0, 2, 0, 0] = 25.064
              diff.mul_(convert).div_(256)
              diff = diff.sum(dim=1, keepdim=True)
      else:
          shave = scale + 6
  
      valid = diff[:, :, shave:-shave, shave:-shave]
      mse = valid.pow(2).mean()
  
      return -10 * math.log10(mse)
  
  
  def make_optimizer(opt, my_model):
      trainable = filter(lambda x: x.requires_grad, my_model.parameters())
      optimizer_function = optim.Adam
      kwargs = {
          'betas': (opt.beta1, opt.beta2),
          'eps': opt.epsilon
      }
      kwargs['lr'] = opt.lr
      kwargs['weight_decay'] = opt.weight_decay
      
      return optimizer_function(trainable, **kwargs)
  
  
  def make_dual_optimizer(opt, dual_models):
      dual_optimizers = []
      for dual_model in dual_models:
          temp_dual_optim = torch.optim.Adam(
              params=dual_model.parameters(),
              lr = opt.lr, 
              betas = (opt.beta1, opt.beta2),
              eps = opt.epsilon,
              weight_decay=opt.weight_decay)
          dual_optimizers.append(temp_dual_optim)
      
      return dual_optimizers
  
  
  def make_scheduler(opt, my_optimizer):
      scheduler = lrs.CosineAnnealingLR(
          my_optimizer,
          float(opt.epochs),
          eta_min=opt.eta_min
      )
  
      return scheduler
  
  
  def make_dual_scheduler(opt, dual_optimizers):
      dual_scheduler = []
      for i in range(len(dual_optimizers)):
          scheduler = lrs.CosineAnnealingLR(
              dual_optimizers[i],
              float(opt.epochs),
              eta_min=opt.eta_min
          )
          dual_scheduler.append(scheduler)
  
      return dual_scheduler
  
  
  def init_model(args):
      # Set the templates here
      if args.model.find('DRN-S') >= 0:
          if args.scale == 4:
              args.n_blocks = 30
              args.n_feats = 16
          elif args.scale == 8:
              args.n_blocks = 30
              args.n_feats = 8
          else:
              print('Use defaults n_blocks and n_feats.')
          args.dual = True
  
      if args.model.find('DRN-L') >= 0:
          if args.scale == 4:
              args.n_blocks = 40
              args.n_feats = 20
          elif args.scale == 8:
              args.n_blocks = 36
              args.n_feats = 10
          else:
              print('Use defaults n_blocks and n_feats.')
          args.dual = True
  
  
  
apis: torch.cuda.manual_seed_all torch.cuda.manual_seed torch.manual_seed numpy.random.seed torch.cuda.device_count