Skip to content

Add I32x16::dot4_u8_i8_add and the U8x64 nibble split on every backend - #386

Merged
AdaWorldAPI merged 2 commits into
masterfrom
claude/dot4-nibble-facade
Oct 29, 2026
Merged

AdaWorldAPI merged 2 commits into
masterfrom
claude/dot4-nibble-facade

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Summary

Three new facade methods, each realized on every backend: AVX-512, AVX2, AVX-only, scalar, NEON, wasm and nightly.

  • I32x16::dot4_u8_i8_add(a: U8x64, b: I8x64) adds a[4j..4j+4] · b[4j..4j+4] (u8 × signed i8) to each i32 lane j.
    • With AVX-512 VNNI compiled in, this is one vpdpbusd.
    • Everywhere else, even and odd bytes are widened into separate 16-bit lanes (zero-extended for a, sign-extended for b), then combined with a 16-bit multiply-add. Every product and partial sum is exact. Only the final addition to the accumulator wraps, as vpdpbusd does.
    • Not the vpmaddubsw emulation: that one saturates each pair sum at i16, and 2 * 255 * 127 = 64 770 clamps to 32 767.
  • U8x64::low_nibbles returns x & 0x0F.
  • U8x64::high_nibbles returns x >> 4. With GFNI compiled in it is a single gf2p8affine; otherwise a 16-bit shift and a mask.

Why: turbovec's VNNI "permute-dot" kernels write this dot product by hand twice, as vpdpbusd on x86 and SDOT on aarch64. They also keep a separate macro variant just for the GFNI high nibble. With these methods in the facade, those kernels can move onto ndarray::simd.

Also fixed: U16x32::to_f32x16_lo/hi on aarch64 and wasm, which came from #385.

  • On those targets U16x32 comes from the scalar file while F32x16 is native.
  • The method therefore returned a type that is not ndarray::simd::F32x16, and the aarch64 lib tests did not compile at all.
  • CI only builds the NEON and wasm parity programs, never the lib tests on those targets, which is how it slipped through.

Tests

simd::dot4_nibble_facade_parity checks four things:

  • results against a plain-array reference, over more than 10 000 cases with byte extremes and i32::MIN/i32::MAX accumulators;
  • the saturation case;
  • that each lane reads only its own four bytes;
  • both nibble methods.

The NEON and wasm parity programs gain the same checks (codes 0x500..), so CI covers those backends too.

Build Path exercised Result
native (AVX-512 + VNNI + GFNI) vpdpbusd, gf2p8affine 4/4
config-v4 (AVX-512, no VNNI/GFNI) widen + vpmaddwd 4/4
config-v3 (AVX2) 256-bit 4/4
config-avx under qemu -cpu SandyBridge SSE2 quarters 4/4
config-v2 under qemu -cpu Nehalem scalar 4/4
aarch64 under qemu NEON 4/4, plus u16x32_facade_parity
nightly-simd core::simd 4/4
scripts/neon-parity.sh, scripts/wasm-parity.sh NEON, wasm pass

Gates:

  • Full lib suite (native): 2657 passed.
  • cargo clippy --config <tier> -- -D warnings: clean on native, v4, v3, v2 and aarch64. The AVX tier's 8 errors already exist on master; none is on an added line.
  • cargo fmt --check: clean.
  • The facade-stride guard is clean on the diff.

Disable runs, each red as expected:

  • an AVX2 vpmaddubsw realization fails the saturation test and the reference test;
  • a wrong GFNI matrix fails the nibble test;
  • vpdpbusds in place of vpdpbusd fails the reference test on the i32::MAX accumulator.

Not done

  • AVX-VNNI: the 256-bit vpdpbusd isn't used on the AVX2 tier.
  • NEON USDOT: not used under i8mm.
  • Signed i8 × i8 form: turbovec's xor 0x80 plus correction has no facade word yet.

None of these is measured.


Generated by Claude Code

dot4_u8_i8_add adds four u8 * i8 products to each i32 lane, the operation
AVX-512 VNNI does with vpdpbusd and turbovec writes by hand twice (vpdpbusd
on x86, SDOT on aarch64). Without VNNI every backend widens even and odd
bytes into 16-bit lanes and uses a 16-bit multiply-add, so no intermediate
saturates; the vpmaddubsw emulation would clamp 2 * 255 * 127 to 32767.
low_nibbles/high_nibbles split each byte; high_nibbles is one gf2p8affine
when GFNI is compiled in.

Also fixes U16x32::to_f32x16_lo/hi on aarch64 and wasm: U16x32 comes from
the scalar file there while F32x16 is native, so the method returned a type
that is not ndarray::simd::F32x16 and the aarch64 lib tests did not compile.

The parity test covers byte and accumulator extremes, the saturation case
and lane placement; the NEON and wasm parity programs check the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMjKnig6MXTd41Lf2v
Adds the saturation trap to the facade contract doc next to the VPABSB
note, and a blackboard entry with the backends witnessed, the disable
runs and the loose ends.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMMjKnig6MXTd41Lf2v
@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2768534d-e378-48e9-8f3c-42cc100912c8
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review October 29, 2026 14:28
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T14:30:11.551435Z 7c4dfe4 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@AdaWorldAPI
AdaWorldAPI merged commit 5b21b14 into master Oct 29, 2026
31 checks passed
AdaWorldAPI pushed a commit that referenced this pull request Oct 29, 2026
…1848

Adds section R2. Rows moved: H1 partly closed by #385 (first U16x32
parity found two AVX-512 bugs); H3 reframed (count_ones lowers to the
same vpshufb nibble table on AVX2, so a rewrite would only hide it);
AVX2 mask_blend set as R2 burn-down item #1 by measurement. New dots
N10-N15: the two 9-bit contracts agree across repos; recall and cost
were measured on different layouts; the AVX2 masked dot hides
compiler-emitted shuffles the source guard cannot see; W4's ndarray
half shipped in #386; the u8->i8 view and R3 are one ruling; NEON and
wasm lib tests are not in CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XAqKMPh2Seh2WLccCksAdY
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