-
Notifications
You must be signed in to change notification settings - Fork 139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The current state of the Wasm port #2819
Comments
Ok, update: I was able to create a Cargo profile that can go even to [profile.wasm-release]
inherits = "release"
# Implicit because of the above inherit, but can be overriden
# by the CARGO_PROFILE_WASM_RELEASE_OPT_LEVEL env var to
# opt-level = 1 to get a more debug-like compile time while
# still optimizing enough to avoid creating an invalid
# artifact with too much locals.
#opt-level = 3
# Currently true in release, which is extremely expensive,
# and false in debug, which is also surprisingly expensive.
lto = "off"
# Creates smaller artifact at the cost of backtraces, which
# sounds like a good tradeoff for the web
panic = "abort"
# Splits the crate into small pieces (default on release is 16).
# With lto="off" this doesn't do link time optimization between
# the results, which keeps a lot of performance on the table,
# but seems to help a lot with max RAM usage.
codegen-units = 256 We can then use this profile in
With This is enough for me to get working on improving the Wasm interface, but I will keep this issue open because the problems I pointed out are still valid. |
I agree with the sentiment of wanting to split the project up into smaller crates; right now doing any change triggers the main build script to run again (to gather the list of atoms used in Before we can do any of that, we would need to change the current system of gathering |
Hell yeah, @bakaq!! This is going to be HUGE!! |
Recently I have been trying to compile the current master of Scryer Prolog to Wasm (specifically the browser version, not WASI yet) to improve the situation there. I faced many hurdles which I will list here so that we are aware of what needs to be improved.
opt-level=1
) takes something like 30GB+ of RAM in my computer (it never completed, and I suspect I would need a lot of swap to make it work). I suspect that the only way to improve the situation here is to split great parts of Scryer Prolog into different crates, because the codegen unit of Rust is a crate and Scryer Prolog is just too big. Obvious candidates are stuff like the parser, the compiler, the rcu, the arena, etc... That would also have many other benefits.Machine::dispatch
is insanely big it actually produces an invalid Wasm artifact. Anything that tries to use it, includingwasm-bindgen
to create the Javascript bindings, errors because the generated function has too many locals. This is a known problem, and there are people trying to improve the situation here in both LLVM and the Wasm spec. LLVM (which is what Rust uses to compile) ideally should detect that it is trying to make an invalid artifact and break the function into smaller pieces if necessary, and the Wasm spec seems to be considering increasing the locals limit. The solution here is to either wait until the rest of the ecosystem improves, or to breakMachine::dispatch
into smaller functions somehow.wasm-opt
with-O1
flag to get some basic optimizations on the Wasm artifact, and that seems to reduce the local count enough for it to be valid.wasm-pack
(which is what one would normally use to compile a Rust project for web) applieswasm-opt
, but only afterwasm-bindgen
, so we can't use it because thenwasm-bindgen
gets the invalid artifact and errors. We need to manually compile,wasm-opt
, and thenwasm-bindgen
.After doing all that just to get a valid artifact, it can't actually run because it imports some functions from a module calledEDIT: This is actually just my Nix setup being weird by default. Installing clang solves this.env
for some reason. This gets bindgen-ed to aimport thing from "env"
in Javascript and makes the bindings unusable because that is not a valid import in the browser. I discovered that this is the fault of thering
dependency, because even using its "Wasm in the browser" feature it accidentally links 2 C functions that don't exist in the Wasm build (this wasn't a problem in their0.16
, which is why this wasn't a problem in Scryer before we updated to0.17
, and also isn't caught by their CI for some reason). I was able to patchring
to fix this and finally get a working artifact, I will report this and the fix to them upstream. The fix here is to either put allring
dependent functionality behind a feature, downgradering
, vendor aring
fork with the patch as a dependency, or wait forring
to release a new version with the fix (which I believe will take quite some time judging by their previous release schedule).TL;DR
Usually to build Wasm Scryer we would just need to run
wasm-pack --target web --no-default-features
, but in current master we actually need to compile in debug mode,wasm-opt -O1
, and thenwasm-bindgen
, all manually.The text was updated successfully, but these errors were encountered: