sig
  type ('data, 'kind) session = ('data, 'kind) Cvode.session
  module Quadrature :
    sig
      type 'd quadrhsfn = float -> '-> '-> unit
      val init :
        ('d, 'k) Cvode.session ->
        'Cvodes.Quadrature.quadrhsfn -> ('d, 'k) Nvector.t -> unit
      val reinit : ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> unit
      val get : ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> float
      val get_dky :
        ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> float -> int -> unit
      type ('d, 'k) tolerance =
          NoStepSizeControl
        | SStolerances of float * float
        | SVtolerances of float * ('d, 'k) Nvector.t
      val set_tolerances :
        ('d, 'k) Cvode.session ->
        ('d, 'k) Cvodes.Quadrature.tolerance -> unit
      val get_num_rhs_evals : ('d, 'k) Cvode.session -> int
      val get_num_err_test_fails : ('d, 'k) Cvode.session -> int
      val get_err_weights :
        ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> unit
      val get_stats : ('d, 'k) Cvode.session -> int * int
      exception QuadNotInitialized
      exception QuadRhsFuncFailure
      exception FirstQuadRhsFuncFailure
      exception RepeatedQuadRhsFuncFailure
      exception UnrecoverableQuadRhsFuncFailure
    end
  module Sensitivity :
    sig
      type 'd sensrhsfn_args = {
        t : float;
        y : 'd;
        y' : 'd;
        tmp : 'Cvode.double;
      }
      type 'd sensrhsfn_all =
          'Cvodes.Sensitivity.sensrhsfn_args ->
          'd array -> 'd array -> unit
      and 'd sensrhsfn1 =
          int -> 'Cvodes.Sensitivity.sensrhsfn_args -> '-> '-> unit
      type 'd sensrhsfn =
          AllAtOnce of 'Cvodes.Sensitivity.sensrhsfn_all option
        | OneByOne of 'Cvodes.Sensitivity.sensrhsfn1 option
      type ('d, 'k) sens_method =
          Simultaneous of
            ('d, 'k, ('d, 'k) Cvode.session, [ `Sens ])
            Sundials.NonlinearSolver.t option
        | Staggered of
            ('d, 'k, ('d, 'k) Cvode.session, [ `Sens ])
            Sundials.NonlinearSolver.t option
        | Staggered1 of
            ('d, 'k, ('d, 'k) Cvode.session, [ `Nvec ])
            Sundials.NonlinearSolver.t option
      type sens_params = {
        pvals : Sundials.RealArray.t option;
        pbar : Sundials.RealArray.t option;
        plist : int array option;
      }
      val no_sens_params : Cvodes.Sensitivity.sens_params
      type ('d, 'k) tolerance =
          SStolerances of float * Sundials.RealArray.t
        | SVtolerances of float * ('d, 'k) Nvector.t array
        | EEtolerances
      val init :
        ('d, 'k) Cvode.session ->
        ('d, 'k) Cvodes.Sensitivity.tolerance ->
        ('d, 'k) Cvodes.Sensitivity.sens_method ->
        ?sens_params:Cvodes.Sensitivity.sens_params ->
        'Cvodes.Sensitivity.sensrhsfn -> ('d, 'k) Nvector.t array -> unit
      val reinit :
        ('d, 'k) Cvode.session ->
        ('d, 'k) Cvodes.Sensitivity.sens_method ->
        ('d, 'k) Nvector.t array -> unit
      val toggle_off : ('d, 'k) Cvode.session -> unit
      val turn_off : ('d, 'k) Cvode.session -> unit
      module Quadrature :
        sig
          type 'd quadsensrhsfn_args = {
            t : float;
            y : 'd;
            s : 'd array;
            yq' : 'd;
            tmp : 'Cvode.double;
          }
          type 'd quadsensrhsfn =
              'Cvodes.Sensitivity.Quadrature.quadsensrhsfn_args ->
              'd array -> unit
          val init :
            ('d, 'k) Cvode.session ->
            ?fqs:'Cvodes.Sensitivity.Quadrature.quadsensrhsfn ->
            ('d, 'k) Nvector.t array -> unit
          val reinit :
            ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t array -> unit
          type ('d, 'k) tolerance =
              NoStepSizeControl
            | SStolerances of float * Sundials.RealArray.t
            | SVtolerances of float * ('d, 'k) Nvector.t array
            | EEtolerances
          val set_tolerances :
            ('d, 'k) Cvode.session ->
            ('d, 'k) Cvodes.Sensitivity.Quadrature.tolerance -> unit
          val get :
            ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t array -> float
          val get1 :
            ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> int -> float
          val get_dky :
            ('d, 'k) Cvode.session ->
            ('d, 'k) Nvector.t array -> float -> int -> unit
          val get_dky1 :
            ('d, 'k) Cvode.session ->
            ('d, 'k) Nvector.t -> float -> int -> int -> unit
          val get_num_rhs_evals : ('d, 'k) Cvode.session -> int
          val get_num_err_test_fails : ('d, 'k) Cvode.session -> int
          val get_err_weights :
            ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t array -> unit
          val get_stats : ('d, 'k) Cvode.session -> int * int
          exception QuadSensNotInitialized
          exception QuadSensRhsFuncFailure
          exception FirstQuadSensRhsFuncFailure
          exception RepeatedQuadSensRhsFuncFailure
          exception UnrecoverableQuadSensRhsFuncFailure
        end
      val get : ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t array -> float
      val get_dky :
        ('d, 'k) Cvode.session ->
        ('d, 'k) Nvector.t array -> float -> int -> unit
      val get1 : ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> int -> float
      val get_dky1 :
        ('d, 'k) Cvode.session ->
        ('d, 'k) Nvector.t -> float -> int -> int -> unit
      val set_tolerances :
        ('d, 'k) Cvode.session ->
        ('d, 'k) Cvodes.Sensitivity.tolerance -> unit
      val set_err_con : ('d, 'k) Cvode.session -> bool -> unit
      type dq_method = DQCentered | DQForward
      val set_dq_method :
        ('d, 'k) Cvode.session ->
        Cvodes.Sensitivity.dq_method -> float -> unit
      val set_max_nonlin_iters : ('d, 'k) Cvode.session -> int -> unit
      val get_num_rhs_evals : ('d, 'k) Cvode.session -> int
      val get_num_rhs_evals_sens : ('d, 'k) Cvode.session -> int
      val get_num_err_test_fails : ('d, 'k) Cvode.session -> int
      val get_num_lin_solv_setups : ('d, 'k) Cvode.session -> int
      type sensitivity_stats = {
        num_sens_evals : int;
        num_rhs_evals : int;
        num_err_test_fails : int;
        num_lin_solv_setups : int;
      }
      val get_stats :
        ('d, 'k) Cvode.session -> Cvodes.Sensitivity.sensitivity_stats
      val get_err_weights :
        ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t array -> unit
      val get_num_nonlin_solv_iters : ('d, 'k) Cvode.session -> int
      val get_num_nonlin_solv_conv_fails : ('d, 'k) Cvode.session -> int
      val get_nonlin_solv_stats : ('d, 'k) Cvode.session -> int * int
      val get_num_stgr_nonlin_solv_iters :
        ('d, 'k) Cvode.session -> Sundials.LintArray.t -> unit
      val get_num_stgr_nonlin_solv_conv_fails :
        ('d, 'k) Cvode.session -> Sundials.LintArray.t -> unit
      val get_current_state_sens : ('d, 'k) Cvodes.session -> 'd array
      type 'd nonlin_system_data = {
        tn : float;
        yspred : 'd array;
        ysn : 'd array;
        gamma : float;
        rls1 : float;
        zns1 : 'd array;
      }
      val get_nonlin_system_data :
        ('d, 'k) Cvodes.session -> 'Cvodes.Sensitivity.nonlin_system_data
      val compute_state :
        ('d, 'k) Cvodes.session ->
        ('d, 'k) Nvector.t array -> ('d, 'k) Nvector.t array -> unit
      val compute_state1 :
        ('d, 'k) Cvodes.session ->
        int -> ('d, 'k) Nvector.t -> ('d, 'k) Nvector.t -> unit
      val get_current_sens_solve_index : ('d, 'k) Cvodes.session -> int
      exception SensNotInitialized
      exception SensRhsFuncFailure
      exception FirstSensRhsFuncFailure
      exception RepeatedSensRhsFuncFailure
      exception UnrecoverableSensRhsFuncFailure
      exception BadSensIdentifier
    end
  module Adjoint :
    sig
      type ('data, 'kind) bsession =
          ('data, 'kind) Cvode_impl.AdjointTypes.bsession
      type 'a serial_bsession =
          (Nvector_serial.data, 'a) Cvodes.Adjoint.bsession
        constraint 'a = [> Nvector_serial.kind ]
      type interpolation = IPolynomial | IHermite
      val init :
        ('d, 'k) Cvode.session -> int -> Cvodes.Adjoint.interpolation -> unit
      val forward_normal :
        ('d, 'k) Cvode.session ->
        float -> ('d, 'k) Nvector.t -> float * int * Cvode.solver_result
      val forward_one_step :
        ('d, 'k) Cvode.session ->
        float -> ('d, 'k) Nvector.t -> float * int * Cvode.solver_result
      type ('data, 'kind) linear_solver =
          ('data, 'kind) Cvode_impl.AdjointTypes.linear_solver
      type 'a serial_linear_solver =
          (Nvector_serial.data, 'a) Cvodes.Adjoint.linear_solver
        constraint 'a = [> Nvector_serial.kind ]
      type 'd triple = 'd * 'd * 'd
      type ('t, 'd) jacobian_arg =
        ('t, 'd) Cvode_impl.AdjointTypes.jacobian_arg = {
        jac_t : float;
        jac_y : 'd;
        jac_yb : 'd;
        jac_fyb : 'd;
        jac_tmp : 't;
      }
      module Diag :
        sig
          val solver : ('data, 'kind) Cvodes.Adjoint.linear_solver
          val get_work_space : ('d, 'k) Cvodes.Adjoint.bsession -> int * int
          val get_num_rhs_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
        end
      module Dls :
        sig
          val dense :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.dense ->
            (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          val lapack_dense :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.dense ->
            (Sundials.Matrix.Dense.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          val band :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.band ->
            (Sundials.Matrix.Band.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          val lapack_band :
            ?context:Sundials.Context.t ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            'Sundials.Matrix.band ->
            (Sundials.Matrix.Band.t, 'a, [ `Dls ])
            Sundials_LinearSolver.serial_t
          module Klu :
            sig
              type ordering =
                Sundials_LinearSolver_impl.Klu.ordering =
                  Amd
                | ColAmd
                | Natural
              val make :
                ?context:Sundials.Context.t ->
                ?ordering:ordering ->
                ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
                ('s, 'a) Sundials.Matrix.sparse ->
                ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
                Sundials_LinearSolver.serial_t
              val reinit :
                ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ] as 'a,
                 [> `Klu ])
                Sundials_LinearSolver.serial_t ->
                ('s, 'a) Sundials.Matrix.sparse -> ?nnz:int -> unit -> unit
              val set_ordering :
                ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
                 [> `Klu ])
                Sundials_LinearSolver.serial_t -> ordering -> unit
            end
          val klu :
            ?context:Sundials.Context.t ->
            ?ordering:Klu.ordering ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Klu ])
            Sundials_LinearSolver.serial_t
          module Superlumt :
            sig
              type ordering =
                Sundials_LinearSolver_impl.Superlumt.ordering =
                  Natural
                | MinDegreeProd
                | MinDegreeSum
                | ColAmd
              val make :
                ?context:Sundials.Context.t ->
                ?ordering:ordering ->
                nthreads:int ->
                ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
                ('s, 'a) Sundials.Matrix.sparse ->
                ('Sundials.Matrix.Sparse.t, 'a, [ `Dls | `Slu ])
                Sundials_LinearSolver.serial_t
              val set_ordering :
                ('Sundials.Matrix.Sparse.t, [> Nvector_serial.kind ],
                 [> `Slu ])
                Sundials_LinearSolver.serial_t -> ordering -> unit
            end
          val superlumt :
            ?context:Sundials.Context.t ->
            ?ordering:Superlumt.ordering ->
            nthreads:int ->
            ([> Nvector_serial.kind ] as 'a) Nvector.serial ->
            ('s, 'a) Sundials.Matrix.sparse ->
            ('Sundials.Matrix.Sparse.t, 'a, [> `Dls | `Slu ])
            Sundials_LinearSolver.serial_t
          type 'm jac_fn_no_sens =
              (Sundials.RealArray.t Cvodes.Adjoint.triple,
               Sundials.RealArray.t)
              Cvodes.Adjoint.jacobian_arg -> '-> unit
          type 'm jac_fn_with_sens =
              (Sundials.RealArray.t Cvodes.Adjoint.triple,
               Sundials.RealArray.t)
              Cvodes.Adjoint.jacobian_arg ->
              Sundials.RealArray.t array -> '-> unit
          type 'm jac_fn =
              NoSens of 'Cvodes.Adjoint.Dls.jac_fn_no_sens
            | WithSens of 'Cvodes.Adjoint.Dls.jac_fn_with_sens
          type 'm linsys_fn_no_sens =
              (Sundials.RealArray.t Cvodes.Adjoint.triple,
               Sundials.RealArray.t)
              Cvodes.Adjoint.jacobian_arg -> '-> bool -> float -> bool
          type 'm linsys_fn_with_sens =
              (Sundials.RealArray.t Cvodes.Adjoint.triple,
               Sundials.RealArray.t)
              Cvodes.Adjoint.jacobian_arg ->
              Sundials.RealArray.t array -> '-> bool -> float -> bool
          type 'm linsys_fn =
              LNoSens of 'Cvodes.Adjoint.Dls.linsys_fn_no_sens
            | LWithSens of 'Cvodes.Adjoint.Dls.linsys_fn_with_sens
          val solver :
            ?jac:'Cvodes.Adjoint.Dls.jac_fn ->
            ?linsys:'Cvodes.Adjoint.Dls.linsys_fn ->
            ('m, Sundials.RealArray.t, [> Nvector_serial.kind ] as 'a, 't)
            Sundials.LinearSolver.t -> 'Cvodes.Adjoint.serial_linear_solver
          val get_work_space :
            [> Nvector_serial.kind ] Cvodes.Adjoint.serial_bsession ->
            int * int
          val get_num_jac_evals :
            [> Nvector_serial.kind ] Cvodes.Adjoint.serial_bsession -> int
          val get_num_lin_rhs_evals :
            [> Nvector_serial.kind ] Cvodes.Adjoint.serial_bsession -> int
        end
      module Spils :
        sig
          type gramschmidt_type =
            Sundials_LinearSolver_impl.Iterative.gramschmidt_type =
              ModifiedGS
            | ClassicalGS
          val spbcgs :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Spbcgs ]) Sundials_LinearSolver.t
          val spfgmr :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ?max_restarts:int ->
            ?gs_type:gramschmidt_type ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Spfgmr ]) Sundials_LinearSolver.t
          val spgmr :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ?max_restarts:int ->
            ?gs_type:gramschmidt_type ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Spgmr ]) Sundials_LinearSolver.t
          val sptfqmr :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Sptfqmr ]) Sundials_LinearSolver.t
          val pcg :
            ?context:Sundials.Context.t ->
            ?maxl:int ->
            ('d, 'k) Nvector.t ->
            ('m, 'd, 'k, [ `Iter | `Pcg ]) Sundials_LinearSolver.t
          module Algorithms :
            sig
              val qr_fact :
                int ->
                Sundials.RealArray2.t -> Sundials.RealArray.t -> bool -> unit
              val qr_sol :
                int ->
                Sundials.RealArray2.t ->
                Sundials.RealArray.t -> Sundials.RealArray.t -> unit
              val modified_gs :
                ('d, 'k) Nvector.t array ->
                Sundials.RealArray2.t -> int -> int -> float
              val classical_gs :
                ('d, 'k) Nvector.t array ->
                Sundials.RealArray2.t ->
                int ->
                int ->
                Sundials.RealArray.t -> ('d, 'k) Nvector.t array -> float
            end
          val set_maxl :
            ('m, 'd, 'k, [< `Iter | `Pcg | `Spbcgs | `Sptfqmr ])
            Sundials_LinearSolver.t -> int -> unit
          val set_gs_type :
            ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ])
            Sundials_LinearSolver.t -> gramschmidt_type -> unit
          val set_max_restarts :
            ('m, 'd, 'k, [< `Iter | `Spfgmr | `Spgmr ])
            Sundials_LinearSolver.t -> int -> unit
          type preconditioning_type =
            Sundials_LinearSolver_impl.Iterative.preconditioning_type =
              PrecNone
            | PrecLeft
            | PrecRight
            | PrecBoth
          val set_prec_type :
            ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
            preconditioning_type -> unit
          val set_info_file :
            ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t ->
            ?print_level:bool -> Sundials.Logfile.t -> unit
          val set_print_level :
            ('m, 'd, 'k, [> `Iter ]) Sundials_LinearSolver.t -> bool -> unit
          type 'd prec_solve_arg = {
            rhs : 'd;
            gamma : float;
            delta : float;
            left : bool;
          }
          type 'd prec_solve_fn =
              (unit, 'd) Cvodes.Adjoint.jacobian_arg ->
              'Cvodes.Adjoint.Spils.prec_solve_arg -> '-> unit
          type 'd prec_solve_fn_with_sens =
              (unit, 'd) Cvodes.Adjoint.jacobian_arg ->
              'Cvodes.Adjoint.Spils.prec_solve_arg ->
              'd array -> '-> unit
          type 'd prec_setup_fn =
              (unit, 'd) Cvodes.Adjoint.jacobian_arg -> bool -> float -> bool
          type 'd prec_setup_fn_with_sens =
              (unit, 'd) Cvodes.Adjoint.jacobian_arg ->
              'd array -> bool -> float -> bool
          type ('d, 'k) preconditioner =
              ('d, 'k) Cvode_impl.AdjointTypes.SpilsTypes.preconditioner
          val prec_none : ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          val prec_left :
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn ->
            'Cvodes.Adjoint.Spils.prec_solve_fn ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          val prec_left_with_sens :
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn_with_sens ->
            'Cvodes.Adjoint.Spils.prec_solve_fn_with_sens ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          val prec_right :
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn ->
            'Cvodes.Adjoint.Spils.prec_solve_fn ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          val prec_right_with_sens :
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn_with_sens ->
            'Cvodes.Adjoint.Spils.prec_solve_fn_with_sens ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          val prec_both :
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn ->
            'Cvodes.Adjoint.Spils.prec_solve_fn ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          val prec_both_with_sens :
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn_with_sens ->
            'Cvodes.Adjoint.Spils.prec_solve_fn_with_sens ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner
          module Banded :
            sig
              type bandrange = { mupper : int; mlower : int; }
              val prec_left :
                Cvodes.Adjoint.Spils.Banded.bandrange ->
                (Nvector_serial.data, [> Nvector_serial.kind ])
                Cvodes.Adjoint.Spils.preconditioner
              val prec_right :
                Cvodes.Adjoint.Spils.Banded.bandrange ->
                (Nvector_serial.data, [> Nvector_serial.kind ])
                Cvodes.Adjoint.Spils.preconditioner
              val prec_both :
                Cvodes.Adjoint.Spils.Banded.bandrange ->
                (Nvector_serial.data, [> Nvector_serial.kind ])
                Cvodes.Adjoint.Spils.preconditioner
              val get_work_space :
                [> Nvector_serial.kind ] Cvodes.Adjoint.serial_bsession ->
                int * int
              val get_num_rhs_evals :
                [> Nvector_serial.kind ] Cvodes.Adjoint.serial_bsession ->
                int
            end
          type 'd jac_times_setup_fn_no_sens =
              (unit, 'd) Cvodes.Adjoint.jacobian_arg -> unit
          type 'd jac_times_setup_fn_with_sens =
              (unit, 'd) Cvodes.Adjoint.jacobian_arg -> 'd array -> unit
          type 'd jac_times_vec_fn_no_sens =
              ('d, 'd) Cvodes.Adjoint.jacobian_arg -> '-> '-> unit
          type 'd jac_times_vec_fn_with_sens =
              ('d, 'd) Cvodes.Adjoint.jacobian_arg ->
              'd array -> '-> '-> unit
          type 'd jac_times_vec_fn =
              NoSens of
                'Cvodes.Adjoint.Spils.jac_times_setup_fn_no_sens option *
                'Cvodes.Adjoint.Spils.jac_times_vec_fn_no_sens
            | WithSens of
                'Cvodes.Adjoint.Spils.jac_times_setup_fn_with_sens option *
                'Cvodes.Adjoint.Spils.jac_times_vec_fn_with_sens
          val solver :
            ('m, 'd, 'k, 'f) Sundials.LinearSolver.t ->
            ?jac_times_vec:'Cvodes.Adjoint.Spils.jac_times_vec_fn ->
            ?jac_times_rhs:'Cvode.rhsfn ->
            ('d, 'k) Cvodes.Adjoint.Spils.preconditioner ->
            ('d, 'k) Cvodes.Adjoint.linear_solver
          val set_jac_eval_frequency :
            ('d, 'k) Cvodes.Adjoint.bsession -> int -> unit
          val set_lsetup_frequency :
            ('d, 'k) Cvodes.Adjoint.bsession -> int -> unit
          val set_eps_lin : ('d, 'k) Cvodes.Adjoint.bsession -> float -> unit
          val set_ls_norm_factor :
            ('d, 'k) Cvodes.Adjoint.bsession -> float -> unit
          val set_linear_solution_scaling :
            ('d, 'k) Cvodes.Adjoint.bsession -> bool -> unit
          val get_work_space : ('d, 'k) Cvodes.Adjoint.bsession -> int * int
          val get_num_lin_iters : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_lin_conv_fails :
            ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_prec_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_prec_solves : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_jtsetup_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_jtimes_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_lin_rhs_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val set_preconditioner :
            ('d, 'k) Cvodes.Adjoint.bsession ->
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn ->
            'Cvodes.Adjoint.Spils.prec_solve_fn -> unit
          val set_preconditioner_with_sens :
            ('d, 'k) Cvodes.Adjoint.bsession ->
            ?setup:'Cvodes.Adjoint.Spils.prec_setup_fn_with_sens ->
            'Cvodes.Adjoint.Spils.prec_solve_fn_with_sens -> unit
          val set_jac_times :
            ('d, 'k) Cvodes.Adjoint.bsession ->
            'Cvodes.Adjoint.Spils.jac_times_vec_fn -> unit
          val clear_jac_times : ('d, 'k) Cvodes.Adjoint.bsession -> unit
        end
      val matrix_embedded_solver :
        (unit, 'data, 'kind, [> `MatE ]) Sundials.LinearSolver.t ->
        ('data, 'kind) Cvodes.Adjoint.linear_solver
      type 'd brhsfn_args =
        'Cvode_impl.AdjointTypes.brhsfn_args = {
        t : float;
        y : 'd;
        yb : 'd;
      }
      type 'd brhsfn_no_sens = 'Cvodes.Adjoint.brhsfn_args -> '-> unit
      type 'd brhsfn_with_sens =
          'Cvodes.Adjoint.brhsfn_args -> 'd array -> '-> unit
      type 'd brhsfn =
          NoSens of 'Cvodes.Adjoint.brhsfn_no_sens
        | WithSens of 'Cvodes.Adjoint.brhsfn_with_sens
      type ('d, 'k) tolerance =
          SStolerances of float * float
        | SVtolerances of float * ('d, 'k) Nvector.t
      val init_backward :
        ('d, 'k) Cvode.session ->
        Cvode.lmm ->
        ('d, 'k) Cvodes.Adjoint.tolerance ->
        ?nlsolver:('d, 'k, ('d, 'k) Cvode.session, [ `Nvec ])
                  Sundials.NonlinearSolver.t ->
        ?lsolver:('d, 'k) Cvodes.Adjoint.linear_solver ->
        'Cvodes.Adjoint.brhsfn ->
        float -> ('d, 'k) Nvector.t -> ('d, 'k) Cvodes.Adjoint.bsession
      module Quadrature :
        sig
          type 'd bquadrhsfn_args = { t : float; y : 'd; yb : 'd; }
          type 'd bquadrhsfn_no_sens =
              'Cvodes.Adjoint.Quadrature.bquadrhsfn_args -> '-> unit
          type 'd bquadrhsfn_with_sens =
              'Cvodes.Adjoint.Quadrature.bquadrhsfn_args ->
              'd array -> '-> unit
          type 'd bquadrhsfn =
              NoSens of 'Cvodes.Adjoint.Quadrature.bquadrhsfn_no_sens
            | WithSens of 'Cvodes.Adjoint.Quadrature.bquadrhsfn_with_sens
          val init :
            ('d, 'k) Cvodes.Adjoint.bsession ->
            'Cvodes.Adjoint.Quadrature.bquadrhsfn ->
            ('d, 'k) Nvector.t -> unit
          val reinit :
            ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> unit
          type ('d, 'k) tolerance =
              NoStepSizeControl
            | SStolerances of float * float
            | SVtolerances of float * ('d, 'k) Nvector.t
          val set_tolerances :
            ('d, 'k) Cvodes.Adjoint.bsession ->
            ('d, 'k) Cvodes.Adjoint.Quadrature.tolerance -> unit
          val get :
            ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> float
          val get_num_rhs_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_num_err_test_fails :
            ('d, 'k) Cvodes.Adjoint.bsession -> int
          val get_err_weights :
            ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> unit
          val get_stats : ('d, 'k) Cvodes.Adjoint.bsession -> int * int
        end
      val backward_normal : ('d, 'k) Cvode.session -> float -> unit
      val backward_one_step : ('d, 'k) Cvode.session -> float -> unit
      val get :
        ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> float
      val get_dky :
        ('d, 'k) Cvodes.Adjoint.bsession ->
        ('d, 'k) Nvector.t -> float -> int -> unit
      val get_y :
        ('d, 'k) Cvode.session -> ('d, 'k) Nvector.t -> float -> unit
      val reinit :
        ('d, 'k) Cvodes.Adjoint.bsession ->
        ?nlsolver:('d, 'k, ('d, 'k) Cvode.session, [ `Nvec ])
                  Sundials.NonlinearSolver.t ->
        ?lsolver:('d, 'k) Cvodes.Adjoint.linear_solver ->
        float -> ('d, 'k) Nvector.t -> unit
      val set_no_sensitivity : ('d, 'k) Cvode.session -> unit
      val set_tolerances :
        ('d, 'k) Cvodes.Adjoint.bsession ->
        ('d, 'k) Cvodes.Adjoint.tolerance -> unit
      val set_max_ord : ('d, 'k) Cvodes.Adjoint.bsession -> int -> unit
      val set_max_num_steps : ('d, 'k) Cvodes.Adjoint.bsession -> int -> unit
      val set_init_step : ('d, 'k) Cvodes.Adjoint.bsession -> float -> unit
      val set_min_step : ('d, 'k) Cvodes.Adjoint.bsession -> float -> unit
      val set_max_step : ('d, 'k) Cvodes.Adjoint.bsession -> float -> unit
      val set_stab_lim_det : ('d, 'k) Cvodes.Adjoint.bsession -> bool -> unit
      val set_constraints :
        ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> unit
      val clear_constraints : ('d, 'k) Cvodes.Adjoint.bsession -> unit
      val get_work_space : ('d, 'k) Cvodes.Adjoint.bsession -> int * int
      val get_num_steps : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_num_rhs_evals : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_num_lin_solv_setups : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_num_err_test_fails : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_last_order : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_current_order : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_last_step : ('d, 'k) Cvodes.Adjoint.bsession -> float
      val get_current_step : ('d, 'k) Cvodes.Adjoint.bsession -> float
      val get_actual_init_step : ('d, 'k) Cvodes.Adjoint.bsession -> float
      val get_current_time : ('d, 'k) Cvodes.Adjoint.bsession -> float
      val get_num_stab_lim_order_reds :
        ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_tol_scale_factor : ('d, 'k) Cvodes.Adjoint.bsession -> float
      val get_err_weights :
        ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> unit
      val get_est_local_errors :
        ('d, 'k) Cvodes.Adjoint.bsession -> ('d, 'k) Nvector.t -> unit
      val get_integrator_stats :
        ('d, 'k) Cvodes.Adjoint.bsession -> Cvode.integrator_stats
      val print_integrator_stats :
        ('d, 'k) Cvodes.Adjoint.bsession -> Stdlib.out_channel -> unit
      val get_num_nonlin_solv_iters : ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_num_nonlin_solv_conv_fails :
        ('d, 'k) Cvodes.Adjoint.bsession -> int
      val get_nonlin_solv_stats :
        ('d, 'k) Cvodes.Adjoint.bsession -> int * int
      exception AdjointNotInitialized
      exception NoForwardCall
      exception ForwardReinitFailure
      exception ForwardFailure
      exception NoBackwardProblem
      exception BadFinalTime
    end
end