Skip to content

feat(wasm): build the full workspace (minus python-native) for browser wasm32 - #144

Merged
Roger-luo merged 1 commit into
mainfrom
wasm-deps
Jun 23, 2026
Merged

feat(wasm): build the full workspace (minus python-native) for browser wasm32#144
Roger-luo merged 1 commit into
mainfrom
wasm-deps

Conversation

@Roger-luo

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #143 (now merged): #143 made the compile gates generic; this PR
closes the dependency / feature-graph blockers so the whole workspace
except ppvm-python-native cross-compiles to wasm32-unknown-unknown
(browser / wasm-bindgen) — cargo build --target wasm32-unknown-unknown with
no extra flags. Native builds keep gxhash/dashmap/ahash/rayon and are
byte-for-byte unchanged.

Mechanism (automatic)

Cargo prunes a dependency under [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
on wasm, but the feature named after it stays on, so #[cfg(feature = "X")]
code would still try to compile against the absent crate. The fix is two
coordinated moves per native-only dep: target-gate the dep and gate its code
sites with the same not(target_arch = "wasm32"). The features then go inert on
wasm, so no default-features = false propagation through the inter-crate deps
is needed
.

Changes

  • ppvm-traits — target-gate ahash/dashmap/gxhash/rayon; gate the
    dashmap map module, the ahash ACMap impls, and the gxhash HashFinalize impl.
  • ppvm-pauli-word — target-gate gxhash.
  • ppvm-pauli-sum — target-gate dashmap/gxhash; gate the
    config::dashmap module and config::indexmap's ByteGxHash/ByteGxHashF64
    (also fixes a latent indexmap-without-gxhash coupling).
  • ppvm-tableau-sum — target-gate gxhash/rayon; word_fingerprint
    falls back from GxHasher to fxhash::FxHasher on wasm (a transient in-memory
    dedup hash, resolved by structurally_equal, never persisted or compared
    across platforms).
  • ppvm-tableau / ppvm-stim — target-gate rayon (no OS threads on wasm).
  • rand entropyrand::make_rng() has no default source on
    wasm32-unknown-unknown, so select getrandom's wasm_js (Web Crypto) backend
    via a --cfg getrandom_backend="wasm_js" rustflag in .cargo/config.toml plus
    the wasm_js feature in ppvm-tableau's wasm-only dep table; feature
    unification covers tableau-sum / stim / top-level ppvm.
  • CI — new wasm32 build (browser) job cross-compiles the workspace on every PR.
  • docs — WebAssembly subsection in develop.astro.

Verification

  • Native cargo test --workspace (excl. python-native's macOS test-link issue):
    744 passed, 0 failed.
  • Native --all-targets and the ppvm-python-native cdylib build unchanged.
  • Full workspace builds for wasm32-unknown-unknown — incl. ppvm-tableau,
    ppvm-tableau-sum, ppvm-stim, and the top-level ppvm crate.
  • On wasm the dependency tree drops ahash/gxhash/getrandom 0.3 entirely,
    leaving only getrandom 0.4 (wasm_js) for rand.

🤖 Generated with Claude Code

…r wasm32

Follow-up to the generic compile gates: makes every crate except
ppvm-python-native cross-compile for wasm32-unknown-unknown (browser /
wasm-bindgen) with no extra flags, while native builds keep gxhash/dashmap/
ahash/rayon and stay byte-for-byte unchanged.

Mechanism (automatic, no per-command flags): the native-only acceleration
deps move into [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tables, so Cargo prunes them on wasm. Their features stay nominally on but
their dep: activations become no-ops, and every code site that names those
crates is gated with the same not(target_arch = "wasm32"), so it compiles
out cleanly.

- ppvm-traits: target-gate ahash/dashmap/gxhash/rayon; gate the dashmap map
  module, the ahash ACMap impls, and the gxhash HashFinalize impl.
- ppvm-pauli-word: target-gate gxhash.
- ppvm-pauli-sum: target-gate dashmap/gxhash; gate the config::dashmap module
  and config::indexmap's ByteGxHash/ByteGxHashF64 (also fixes a latent
  indexmap-without-gxhash coupling).
- ppvm-tableau-sum: target-gate gxhash/rayon; word_fingerprint falls back from
  GxHasher to fxhash::FxHasher on wasm (it is a transient in-memory dedup hash
  resolved by structurally_equal, never persisted or compared cross-platform).
- ppvm-tableau / ppvm-stim: target-gate rayon (no OS threads on wasm).
- rand entropy: rand::make_rng() has no default source on
  wasm32-unknown-unknown, so select getrandom's wasm_js (Web Crypto) backend
  via a --cfg getrandom_backend="wasm_js" rustflag in .cargo/config.toml plus
  the wasm_js feature in ppvm-tableau's wasm-only dep table; feature
  unification covers tableau-sum/stim/top-level ppvm.
- CI: new 'wasm32 build (browser)' job cross-compiles the workspace on every PR.
- docs: WebAssembly subsection in develop.astro.

Verified: native cargo test --workspace = 744 passed, 0 failed; native
--all-targets and the ppvm-python-native cdylib build unchanged; the full
workspace (incl. ppvm-tableau, ppvm-tableau-sum, ppvm-stim, top-level ppvm)
builds for wasm32-unknown-unknown; and on wasm the dependency tree drops
ahash/gxhash/getrandom-0.3 entirely, leaving only getrandom 0.4 (wasm_js) for
rand entropy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-23 06:19 UTC

@Roger-luo

Copy link
Copy Markdown
Collaborator Author

No performance impact on native builds. Every change in this PR is wasm-only — a cfg(not(target_arch = "wasm32")) dependency-table move or code gate, or the new FingerprintHasher alias that resolves to the existing GxHasher on native — so the native dependency + feature tree is byte-for-byte identical to main and the compiled native code is unchanged. A ppvm-tableau-sum storage_compare comparison against a main baseline confirmed this empirically: the deltas were pure measurement noise (the vec path, which this PR cannot touch, swung +8.9% then −3.2% across two runs of the identical binary).

@Roger-luo

Copy link
Copy Markdown
Collaborator Author

I think WASM is fully supported now.

cc: @rafaelha

@Roger-luo
Roger-luo merged commit c44d811 into main Jun 23, 2026
14 checks passed
@Roger-luo
Roger-luo deleted the wasm-deps branch June 23, 2026 06:19
@rafaelha

Copy link
Copy Markdown
Collaborator

Confirming that WASM compilation works for me now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants