SleipnirGroup / Sleipnir

A linearity-exploiting sparse nonlinear constrained optimization problem solver that uses the interior-point method.
BSD 3-Clause "New" or "Revised" License
45 stars 10 forks source link

Add Rust bindings #559

Open calcmogul opened 5 months ago

calcmogul commented 5 months ago

This would make it possible for Choreo to call the solver directly in Tauri.

Use Jormungandr as a reference for what to bind. Instead of NumPy, use nalgebra.

We need to be able to overload the math operators (see https://doc.rust-lang.org/core/ops/) for various combinations of:

We also need to overload the equality operator to return a constraint object instead of bool; and overload the comparison operators to return a constraint object instead of Ordering. If that's not possible, provide the following:

BBScholar commented 5 months ago

Not sure if there's an alternative method, but I'm pretty sure rust's bindgen won't play nicely with Sleipnir. More specifically, bindgen does not handle templated functions or methods of templated classes.

See here: https://rust-lang.github.io/rust-bindgen/cpp.html#unsupported-features

calcmogul commented 5 months ago

Neither did pybind11 when I wrote the Python bindings, because templates are... templates for creating classes/functions, not classes/functions themselves. What you have to do is create specific instantiations, then wrap those. That happened transparently in pybind11:

void BindVariableBlock(py::module_& autodiff,
                       py::class_<VariableBlock<VariableMatrix>>& cls) {
  ...
  cls.def(
      "set_value",
      [](VariableBlock<VariableMatrix>& self, double value) {
        self.SetValue(value);
      },
      "value"_a, DOC(sleipnir, VariableBlock, SetValue));

The bindgen docs saying it doesn't support inline functions is concerning, because every function in Sleipnir is inline. We export them from the DLL, so I don't see why it shouldn't be able to link to and use them like pybind11 can.

Not calling destructors is also super wack, cuz destructors are the bread-and-butter of C++ (and Rust).