Repository navigation
feat(hpc): codec8 phase (b) — keep ties-away encode vector on wasm - #371
AdaWorldAPI wants to merge 1 commit into
Conversation
The codegen check for phase (b) of .claude/plans/quantized-codec8-v2.md found one arm that leaves the vector unit: on wasm32+simd128, f32::round (round half away) has no vector instruction, so the TFLite encode loop made four roundf calls per f32x4. x86 v3/v4 and aarch64 were already fully vector and generic == hand-written. TiesAway::round now uses trunc plus a half test on wasm32 only (cfg, no runtime dispatch); other targets keep f32::round, so their assembly is unchanged (scripts/codec8_asm_diff.sh: v3 283/295, v4 278/295, IDENTICAL). On wasm the loop is now f32x4.trunc/sub/abs/ge/bitselect, zero roundf calls. Equality of the trunc form with f32::round: 0 mismatches over all 2^32 bit patterns natively, and over 2^32 - 1 run in node's wasm engine (simd128 build). A strided unit test plus half-integer neighbourhoods keeps it pinned on every target. No new SIMD primitives: every other arm is already vectorised by LLVM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Closing this PR because its premise is wrong. It treats LLVM auto-vectorisation of a scalar loop as the vector implementation, and wins that vectorisation back on wasm with a Generated by Claude Code |
What
Phase (b) of
.claude/plans/quantized-codec8-v2.md, follow-up to #370. Before adding SIMD primitives, I checked each arm's generated code. The vector contract's codegen-oracle rule says a loop counts as scalar only if the assembly shows it is.lane_even,onnx)tflite_act)vdivps,vroundps)fdiv v.4s,frintx)f32x4.div,f32x4.nearest)roundfcalls perf32x4wasm has no vector round-half-away instruction. So
TiesAway::roundnow usestruncplus a half test onwasm32only, chosen bycfgwith no runtime dispatch. Every other target keepsf32::round. After the change, the wasm loop isf32x4.trunc/sub/abs/ge/bitselect, with noroundfcalls and no lane extracts.No new SIMD primitives. Every arm is already vectorised by LLVM, so adding primitives under W1a would add surface area without adding speed.
Evidence
f32::round: 0 mismatches over all 2³² bit patterns natively. Run in node's wasm engine (simd128 build), also 0 mismatches over 2³²−1; the skipped pattern0xFFFFFFFFis a NaN.>=→>fails it.scripts/codec8_asm_diff.shgives v3 283/295 and v4 278/295 lines, generic vs hand-written IDENTICAL, and the negative control differs.lane_evenare identical. Fortflite_actthe instruction multisets are identical; only the placement of the length-check error block differs. That difference was there before this change.cargo test --release --lib hpc::codec8: 17 passed. Clippy (-D warnings, lib + example) and fmt are clean.Not measured: wasm timing. The claim here is codegen (vector, no libm calls), not speed.
Generated by Claude Code