libDF: enable wasm_simd on rustfft and realfft#687
Open
czoli1976 wants to merge 1 commit into
Open
Conversation
Both `rustfft` and `realfft` ship comprehensive WASM SIMD paths gated behind a non-default `wasm_simd` feature flag. Without it, FFTs fall back to scalar on wasm32 even when the build has `+simd128` enabled. For libDF's STFT path (which goes through realfft), both crates' flags must be enabled for the SIMD code to actually execute. ## Changes `libDF/Cargo.toml`: - `rustfft`: keep `^6.1.0` constraint (lockfile-resolved 6.2.0 already has the feature), add `features = ["wasm_simd"]`. - `realfft`: bump constraint from `^3.1.0` to `^3.5` (the `wasm_simd` feature was first added in 3.5.0), add `features = ["wasm_simd"]`. `Cargo.lock`: realfft 3.3.0 → 3.5.0, with workspace-wide cascade. The lockfile churn is large because libDF's resolution hasn't been refreshed in a while; touching realfft triggers re-resolution of dependents. If the noise is unwanted, reverting the lockfile and leaving downstream `cargo update` to handle it is safe — the Cargo.toml change is what matters. ## Impact On wasm32, the WASM SIMD path produces ~2.4× faster FFTs at DFN3-relevant sizes. Isolated bench (wasmtime/Cranelift, M-class Mac) on FFT round-trips: | FFT size | scalar | with wasm_simd | Δ | |---------------------|--------:|---------------:|-----:| | n=480 (DFN3 STFT) | 3042 ns | 1280 ns | -58% | | n=1024 (pow2) | 5906 ns | 2482 ns | -58% | | n=2048 | 12051 ns| 5324 ns | -56% | End-to-end DFN3 RTF impact is small (~1-2% on V8, within noise on Cranelift) because FFT is roughly 1% of DFN3's per-hop budget. The gain is much larger for FFT-bound workloads (Whisper, vocoders, music processing, pure DSP code). The flag is a no-op on non-wasm targets — native ARM (NEON) and x86 (AVX/SSE) paths are unchanged. ## Testing `cargo build --release --target=wasm32-wasip1 --features=wasm` succeeds with the new constraint and produces a binary that emits WASM SIMD ops in the FFT codepath (verified via `wasm-objdump -d`). ## Companion PR Tract has the same gap; companion PR at sonos/tract: enabling rustfft's `wasm_simd` feature at the workspace level for any tract WASM consumer that uses FFT through `tract-onnx-opl` directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Both
rustfftandrealfftship comprehensive WASM SIMD paths gated behind a non-defaultwasm_simdfeature flag. Without it, FFTs fall back to scalar onwasm32even when the build has+simd128enabled. For libDF's STFT path (which goes through realfft, with rustfft as a transitive dep withdefault-features = false), both crates' flags must be enabled for the SIMD code to actually flow through to runtime.Changes
libDF/Cargo.toml:rustfft: keep^6.1.0constraint (the lockfile-resolved 6.2.0 already has thewasm_simdfeature), addfeatures = ["wasm_simd"].realfft: bump constraint from^3.1.0to^3.5(thewasm_simdfeature was first added in 3.5.0), addfeatures = ["wasm_simd"].Cargo.lock: realfft 3.3.0 → 3.5.0, with workspace-wide cascade. The lockfile diff is large (~80 crate version changes) because libDF's resolution hasn't been refreshed in a while; touching realfft triggers re-resolution of dependents. If the noise is unwanted, reverting just the lockfile and leaving downstreamcargo updateto handle it is safe — thelibDF/Cargo.tomlchange is what matters for behavior.Impact
On wasm32, the WASM SIMD path produces ~2.4× faster FFTs at DFN3-relevant sizes. Isolated bench (wasmtime / Cranelift, M-class Mac) on FFT round-trips:
End-to-end DFN3 RTF impact is small (within noise on wasmtime, ~1.9% on Node 22 / V8) because FFT is roughly 1% of DFN3's per-hop budget at 48 kHz with hop=480. The gain is much larger for FFT-bound workloads (Whisper, vocoders, music processing, pure DSP code).
The flag is a no-op on non-wasm targets — native ARM (NEON) and x86 (AVX/SSE) paths are unchanged.
Testing
succeeds with the new constraint. Standalone DFN3 RTF bench against vendored libDF (30s synthetic test signal, 3 timed passes per build, min-of-3, hop_size=480, sr=48000):
Companion PR
Tract has the same gap at the workspace level: sonos/tract#2205. The two PRs are independent — both should land for the full SIMD path to flow on wasm32 builds that use libDF.
🤖 Generated with Claude Code