rust-or / highs

Safe rust bindings to the Highs MILP Solver.
https://crates.io/crates/highs
MIT License
20 stars 11 forks source link

Adding wasm support (feature) #7

Open regular-citizen opened 1 year ago

regular-citizen commented 1 year ago

Hello, I'm opening this issue to discuss the option to upstream some changes we implemented to add support for HiGHS in wasm32-unkown-unknown targets.

This is a somewhat non-trivial business, but was necessary in our use case to get access to a fast LP solver from the browser. Since we have figured out how to do it, we thought we may spare someone else the trouble.

The current strategy we are using works as follows. I have a forked version of your crate (here), which intercepts the calls to highs-sys and instead runs them through wasm-bindgen to some external symbols, which are placed in the global JS scope.

We then take the highs library and compile it to C++ with emscripten. Unfortunately, this means it is ABI-incompatible with wasm32-unknown-unknown, so we cannot directly link against our main rust binaries. But we have written some light glue code that allows us to pretend we have a JS implementation of the highs-sys functionality. Thanks to the architecture of your crate, the shim is not too extensive.

The full nix derivation for buildings highs with emscripten and adding our bindings can be found here.

Overall, this works reliably in practice. There is a subtle memory corruption bug, for which we would appreciate help with debugging, but we have been successful in avoiding it by slightly padding the LP problems. Aside from this, it is pretty much done and good to be merged.

lovasoa commented 1 year ago

Hi, and thanks for opening this !

Is there an advantage to the technique you describe over compiling for the wasm32-unknown-emscripten directly ? Wouldn't it be easier than compiling highs with emscripten separately ?

NickHu commented 1 year ago

The reason is that the Rust + web story forces you to compile for wasm32-unknown-unknown. Pretty much every Rust project that compiles to WASM to run in the browser is like this.

See https://rustwasm.github.io/docs/book/reference/add-wasm-support-to-crate.html for more information.

jajhall commented 1 year ago

Happy to hear that you've chicaned around this @regular-citizen, but all Greek to me! Great that we've got folk in the rust community to bring HiGHS into play.

regular-citizen commented 1 year ago

HiGHS is genuinely an impressive piece of software. We use it to power all the coordinate computations for our proof graphical assistant, and it massively outperforms all the pure rust alternatives.

The integration was worth it, but the fact that HiGHS requires a completely different toolchain to compile caused a lot of headaches and required all the above hacks.

lovasoa commented 1 year ago

Just a note since this issue seems to have an audience: the easiest way to run highs on the web is probably highs-js : https://github.com/lovasoa/highs-js

It's highs compiled to wasm and distributed on npm as a js library