code: def _allreduce_grad_async(self, p):
      # Delta optimizer implements this logic:
      #  start = current.copy()
      #  step() -> computes 'current - \alpha.f(g)' where f is
      #            optimizer logic and g is the gradient
      #  delta = current-start
      #  allreduce_(delta)
      #  start += delta
      #  current = start
      # In order to suppport this logic using function hook to improve performance,
      # we do:
      # delta = (start - \alpha.f(g)) - start
      #       = -\alpha.f(g)
      # set start to zero and step computes -\alpha.f(g)
      # where f is the underlying optimizer logic
  
      name = self._parameter_names.get(p)
      start = self._starting_models[p]
  
      stashed_params = []
      for group in self.param_groups:
          stashed_params.append(group["params"])
          # only want to step on p
          if any([p is v for v in group["params"]]):
              group["params"] = [p]
          else:
              group["params"] = []
  
      start.data.copy_(p)
  
      super(self.__class__, self).step()
  
      # compute delta = curr - start
      p.data.sub_(start)
  
      # allreduce as before
      tensor_compressed, ctx = self._compression.compress(p)
      handle = allreduce_async_(
          tensor_compressed.data, name=name, op=Adasum
      )
  
      # reset stashed parameters
      for stashed, group in zip(stashed_params, self.param_groups):
          group["params"] = stashed
  
      return handle, ctx
  
imports: import os
  import warnings
  from contextlib import contextmanager
  import torch
  from horovod.common.util import split_list
  from horovod.torch.compression import Compression
  from horovod.torch.functions import broadcast_object
  from horovod.torch.mpi_ops import allreduce_async_, grouped_allreduce_async_, sparse_allreduce_async
  from horovod.torch.mpi_ops import synchronize
  from horovod.torch.mpi_ops import size
  from horovod.torch.mpi_ops import Average, Adasum, Sum
  from horovod.torch.mpi_ops import rocm_built
  from horovod.torch.mpi_ops import ProcessSet, global_process_set
label_desc: Use image node_id 4 for calling the _DistributedAdasumOptimizer obj's underlying member method code with example usage: obj._allreduce_grad_async(p) and returns: handle,  ctx