code: def backward(ctx, grad_ys, *grad_extra_solver_state):  # noqa
      ys, ts, *extras_and_adjoint_params = ctx.saved_tensors
      if ctx.saved_extras_for_backward:
          extra_solver_state = extras_and_adjoint_params[
              : ctx.len_extras
          ]
          adjoint_params = extras_and_adjoint_params[ctx.len_extras :]
      else:
          grad_extra_solver_state = ()
          extra_solver_state = None
          adjoint_params = extras_and_adjoint_params
  
      aug_state = (
          [ys[-1], grad_ys[-1]]
          + list(grad_extra_solver_state)
          + [torch.zeros_like(param) for param in adjoint_params]
      )
      shapes = [t.size() for t in aug_state]
      aug_state = misc.flatten(aug_state)
      aug_state = aug_state.unsqueeze(0)  # dummy batch dimension
      adjoint_sde = AdjointSDE(ctx.sde, adjoint_params, shapes)
      reverse_bm = ReverseBrownian(ctx.bm)
  
      solver_fn = methods.select(
          method=ctx.adjoint_method, sde_type=adjoint_sde.sde_type
      )
      solver = solver_fn(
          sde=adjoint_sde,
          bm=reverse_bm,
          dt=ctx.dt,
          adaptive=ctx.adjoint_adaptive,
          rtol=ctx.adjoint_rtol,
          atol=ctx.adjoint_atol,
          dt_min=ctx.dt_min,
          options=ctx.adjoint_options,
      )
      if extra_solver_state is None:
          extra_solver_state = solver.init_extra_solver_state(
              ts[-1], aug_state
          )
  
      for i in range(ys.size(0) - 1, 0, -1):
          (
              _,
              aug_state,
          ), *extra_solver_state = _SdeintAdjointMethod.apply(
              adjoint_sde,
              torch.stack([-ts[i], -ts[i - 1]]),
              ctx.dt,
              reverse_bm,
              solver,
              ctx.adjoint_method,
              ctx.adjoint_method,
              ctx.adjoint_adaptive,
              ctx.adjoint_rtol,
              ctx.adjoint_atol,
              ctx.dt_min,
              ctx.adjoint_options,
              len(extra_solver_state),
              aug_state,
              *extra_solver_state,
              *adjoint_params,
          )
          aug_state = misc.flat_to_shape(aug_state.squeeze(0), shapes)
          aug_state[0] = ys[i - 1]
          aug_state[1] = aug_state[1] + grad_ys[i - 1]
          if i != 1:
              aug_state = misc.flatten(aug_state)
              aug_state = aug_state.unsqueeze(
                  0
              )  # dummy batch dimension
  
      if ctx.saved_extras_for_backward:
          out = aug_state[1:]
      else:
          out = (
              [aug_state[1]] + ([None] * ctx.len_extras) + aug_state[2:]
          )
      return (
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          None,
          *out,
      )
  
file_path: torchsde/torchsde/_core/adjoint.py
imports: import torch
  from torch import nn
  import warnings
  from .None import base_sde
  from .None import methods
  from .None import misc
  from .None import sdeint
  from .adjoint_sde import AdjointSDE
  from .._brownian import BaseBrownian, ReverseBrownian
  from ..settings import METHODS, NOISE_TYPES, SDE_TYPES
  from ..types import Any, Dict, Optional, Scalar, Tensor, Tensors, TensorOrTensors, Vector
label_desc: Use image node_id 2 for calling the _SdeintAdjointMethod obj's underlying member method code with example usage: obj.backward(ctx, grad_ys) and returns: None,  None,  None,  None,  None,  None,  None,  None,  None,  None,  None,  None,  None,  unknown