code: def check_contract(
      sde, y0, ts, bm, method, adaptive, options, names, logqp
  ):
      if names is None:
          names_to_change = {}
      else:
          names_to_change = {
              key: names[key]
              for key in (
                  "drift",
                  "diffusion",
                  "prior_drift",
                  "drift_and_diffusion",
                  "drift_and_diffusion_prod",
              )
              if key in names
          }
      if len(names_to_change) > 0:
          sde = base_sde.RenameMethodsSDE(sde, **names_to_change)
  
      if not hasattr(sde, "noise_type"):
          raise ValueError(
              "sde does not have the attribute noise_type."
          )
  
      if sde.noise_type not in NOISE_TYPES:
          raise ValueError(
              f"Expected noise type in {NOISE_TYPES}, but found {sde.noise_type}."
          )
  
      if not hasattr(sde, "sde_type"):
          raise ValueError("sde does not have the attribute sde_type.")
  
      if sde.sde_type not in SDE_TYPES:
          raise ValueError(
              f"Expected sde type in {SDE_TYPES}, but found {sde.sde_type}."
          )
  
      if not torch.is_tensor(y0):
          raise ValueError("`y0` must be a torch.Tensor.")
      if y0.dim() != 2:
          raise ValueError(
              "`y0` must be a 2-dimensional tensor of shape (batch, channels)."
          )
  
      # --- Backwards compatibility: v0.1.1. ---
      if logqp:
          sde = base_sde.SDELogqp(sde)
          y0 = torch.cat(
              (y0, y0.new_zeros(size=(y0.size(0), 1))), dim=1
          )
      # ----------------------------------------
  
      if method is None:
          method = {
              SDE_TYPES.ito: {
                  NOISE_TYPES.diagonal: METHODS.srk,
                  NOISE_TYPES.additive: METHODS.srk,
                  NOISE_TYPES.scalar: METHODS.srk,
                  NOISE_TYPES.general: METHODS.euler,
              }[sde.noise_type],
              SDE_TYPES.stratonovich: METHODS.midpoint,
          }[sde.sde_type]
  
      if method not in METHODS:
          raise ValueError(
              f"Expected method in {METHODS}, but found {method}."
          )
  
      if not torch.is_tensor(ts):
          if not isinstance(ts, (tuple, list)) or not all(
              isinstance(t, (float, int)) for t in ts
          ):
              raise ValueError(
                  "Evaluation times `ts` must be a 1-D Tensor or list/tuple of floats."
              )
          ts = torch.tensor(ts, dtype=y0.dtype, device=y0.device)
      if not misc.is_strictly_increasing(ts):
          raise ValueError(
              "Evaluation times `ts` must be strictly increasing."
          )
  
      batch_sizes = []
      state_sizes = []
      noise_sizes = []
      batch_sizes.append(y0.size(0))
      state_sizes.append(y0.size(1))
      if bm is not None:
          if len(bm.shape) != 2:
              raise ValueError(
                  "`bm` must be of shape (batch, noise_channels)."
              )
          batch_sizes.append(bm.shape[0])
          noise_sizes.append(bm.shape[1])
  
      def _check_2d(name, shape):
          if len(shape) != 2:
              raise ValueError(
                  f"{name} must be of shape (batch, state_channels), but got {shape}."
              )
          batch_sizes.append(shape[0])
          state_sizes.append(shape[1])
  
      def _check_2d_or_3d(name, shape):
          if sde.noise_type == NOISE_TYPES.diagonal:
              if len(shape) != 2:
                  raise ValueError(
                      f"{name} must be of shape (batch, state_channels), but got {shape}."
                  )
              batch_sizes.append(shape[0])
              state_sizes.append(shape[1])
              noise_sizes.append(shape[1])
          else:
              if len(shape) != 3:
                  raise ValueError(
                      f"{name} must be of shape (batch, state_channels, noise_channels), but got {shape}."
                  )
              batch_sizes.append(shape[0])
              state_sizes.append(shape[1])
              noise_sizes.append(shape[2])
  
      has_f = False
      has_g = False
      if hasattr(sde, "f"):
          has_f = True
          f_drift_shape = tuple(sde.f(ts[0], y0).size())
          _check_2d("Drift", f_drift_shape)
      if hasattr(sde, "g"):
          has_g = True
          g_diffusion_shape = tuple(sde.g(ts[0], y0).size())
          _check_2d_or_3d("Diffusion", g_diffusion_shape)
      if hasattr(sde, "f_and_g"):
          has_f = True
          has_g = True
          _f, _g = sde.f_and_g(ts[0], y0)
          f_drift_shape = tuple(_f.size())
          g_diffusion_shape = tuple(_g.size())
          _check_2d("Drift", f_drift_shape)
          _check_2d_or_3d("Diffusion", g_diffusion_shape)
      if hasattr(sde, "g_prod"):
          has_g = True
          if len(noise_sizes) == 0:
              raise ValueError(
                  "Cannot infer noise size (i.e. number of Brownian motion channels). Either pass `bm` "
                  "explicitly, or specify one of the `g`, `f_and_g` functions.`"
              )
          v = torch.randn(
              batch_sizes[0],
              noise_sizes[0],
              dtype=y0.dtype,
              device=y0.device,
          )
          g_prod_shape = tuple(sde.g_prod(ts[0], y0, v).size())
          _check_2d("Diffusion-vector product", g_prod_shape)
      if hasattr(sde, "f_and_g_prod"):
          has_f = True
          has_g = True
          if len(noise_sizes) == 0:
              raise ValueError(
                  "Cannot infer noise size (i.e. number of Brownian motion channels). Either pass `bm` "
                  "explicitly, or specify one of the `g`, `f_and_g` functions.`"
              )
          v = torch.randn(
              batch_sizes[0],
              noise_sizes[0],
              dtype=y0.dtype,
              device=y0.device,
          )
          _f, _g_prod = sde.f_and_g_prod(ts[0], y0, v)
          f_drift_shape = tuple(_f.size())
          g_prod_shape = tuple(_g_prod.size())
          _check_2d("Drift", f_drift_shape)
          _check_2d("Diffusion-vector product", g_prod_shape)
  
      if not has_f:
          raise ValueError(
              "sde must define at least one of `f`, `f_and_g`, or `f_and_g_prod`. (Or possibly more "
              "depending on the method chosen.)"
          )
      if not has_g:
          raise ValueError(
              "sde must define at least one of `g`, `f_and_g`, `g_prod` or `f_and_g_prod`. (Or possibly "
              "more depending on the method chosen.)"
          )
  
      for batch_size in batch_sizes[1:]:
          if batch_size != batch_sizes[0]:
              raise ValueError("Batch sizes not consistent.")
      for state_size in state_sizes[1:]:
          if state_size != state_sizes[0]:
              raise ValueError("State sizes not consistent.")
      for noise_size in noise_sizes[1:]:
          if noise_size != noise_sizes[0]:
              raise ValueError("Noise sizes not consistent.")
  
      if sde.noise_type == NOISE_TYPES.scalar:
          if noise_sizes[0] != 1:
              raise ValueError(
                  f"Scalar noise must have only one channel; the diffusion has {noise_sizes[0]} noise "
                  f"channels."
              )
  
      sde = base_sde.ForwardSDE(sde)
  
      if bm is None:
          if method == METHODS.srk:
              levy_area_approximation = (
                  LEVY_AREA_APPROXIMATIONS.space_time
              )
          elif method == METHODS.log_ode_midpoint:
              levy_area_approximation = LEVY_AREA_APPROXIMATIONS.foster
          else:
              levy_area_approximation = LEVY_AREA_APPROXIMATIONS.none
          bm = BrownianInterval(
              t0=ts[0],
              t1=ts[-1],
              size=(batch_sizes[0], noise_sizes[0]),
              dtype=y0.dtype,
              device=y0.device,
              levy_area_approximation=levy_area_approximation,
          )
  
      if options is None:
          options = {}
      else:
          options = options.copy()
  
      if (
          adaptive
          and method == METHODS.euler
          and sde.noise_type != NOISE_TYPES.additive
      ):
          warnings.warn(
              "Numerical solution is not guaranteed to converge to the correct solution when using adaptive "
              "time-stepping with the Euler--Maruyama method with non-additive noise."
          )
  
      return sde, y0, ts, bm, method, options
  
file_path: torchsde/torchsde/_core/sdeint.py
imports: import warnings
  import torch
  from .None import base_sde
  from .None import methods
  from .None import misc
  from .._brownian import BaseBrownian, BrownianInterval
  from ..settings import LEVY_AREA_APPROXIMATIONS, 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 a global function with example usage: check_contract(sde, y0, ts, bm, method, adaptive, options, names, logqp) and returns: sde,  y0,  ts,  bm,  method,  options