code: def __init__(self, fn, args, kwargs) -> None:
      self._inputs = []
      self._fns = []
      self.next_functions = []
      for idx, input in [*enumerate(args), *kwargs.items()]:
          if (
              isinstance(input, torch_frontend.Tensor)
              and input.requires_grad
          ):
              self._inputs.append(input.detach())
  
              def wrap_fn(idx):
                  def d_fn(x):
                      if idx in kwargs:
                          return fn(
                              *args,
                              **{
                                  key: value
                                  for key, value in kwargs.items()
                                  if key != idx
                              },
                              idx=x,
                          )
                      return fn(
                          *args[:idx], x, *args[idx + 1 :], **kwargs
                      )
  
                  return d_fn
  
              self._fns.append(
                  to_ivy_arrays_and_back(ivy.jac(wrap_fn(idx)))
              )
              if input.grad_fn is not None:
                  self.next_functions.append(input.grad_fn)
              elif input.is_leaf:
                  acc_grad = AccumulateGrad()
                  acc_grad.__self__ = input
                  self.next_functions.append(acc_grad)
      self.__name__ = fn.__name__.capitalize() + "Backward"
  
imports: import functools
  from typing import Callable
  import ivy
  import ivy.functional.frontends.torch
label_desc: Use image node_id 1 to create a new GradFn object  with example: obj = GradFn(fn, args, kwargs)