code: def update(self, lossfun=None, *args, **kwds):
      target = self.target
      if lossfun is not None:
          use_cleargrads = getattr(self, "_use_cleargrads", True)
          loss = lossfun(*args, **kwds)
          if use_cleargrads:
              target.cleargrads()
          else:
              target.zerograds()
          loss.backward(loss_scale=self.actual_optimizer._loss_scale)
          del loss
  
      if self.is_changed(target, self.target_params_list[0]):
          self.wait()
          self.communicator.bcast_data(target)
          super(_DoubleBufferingOptimizer, self).__setattr__(
              "communicated_target", copy.deepcopy(target)
          )
          super(_DoubleBufferingOptimizer, self).__setattr__(
              "target_params_list",
              [
                  list(sorted(self.target.namedparams())),
                  list(sorted(self.communicated_target.namedparams())),
              ],
          )
          super(_DoubleBufferingOptimizer, self).__setattr__(
              "needs_update", False
          )
      else:
          self.wait()
          self.swap_grad(
              self.target_params_list[0], self.target_params_list[1]
          )
          self.multi_node_mean_grad_async()
          if self.needs_update:
              self.actual_optimizer.update(None, *args, **kwds)
          else:
              super(_DoubleBufferingOptimizer, self).__setattr__(
                  "needs_update", True
              )
  
imports: import chainer
  import copy
label_desc: Use image node_id 2 for calling the _DoubleBufferingOptimizer obj's underlying member method code with example usage: obj.update(lossfun) without return types