Skip to content

simd: U64x8::transpose8 — the 8×8 u64 cross-lane transpose, all six backends - #332

Merged
AdaWorldAPI merged 2 commits into
masterfrom
claude/u64x8-transpose8
Sep 25, 2026
Merged

AdaWorldAPI merged 2 commits into
masterfrom
claude/u64x8-transpose8

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What

U64x8::transpose8(rows: [U64x8; 8]) -> [U64x8; 8], where out[i] lane j == rows[j] lane i. It is implemented on every backend:

backend body
AVX-512 8 unpacklo/hi_epi64, then 16 vshufi64x2, for 24 shuffles
AVX2 four 4×4 blocks (unpack + vperm2i128, 8 each); the off-diagonal blocks trade places by choice of destination only
NEON 32 vtrn1q_u64/vtrn2q_u64 on 2×2 blocks; block placement is register renaming
wasm 32 i64x2_shuffle, same structure as NEON
scalar / nightly the index map (this is the reference the other backends are tested against)

Why a transpose

Argon2's Block::compress needs exactly one cross-lane move. I counted how many words change lane between stages (8 lanes, choice of register free):

layout load→row in row pass row→col in col pass col→store total
vertical (lane = permutation) 112 0 112 0 112 336
horizontal (lane-rotation diagonalize) 64 96 112 96 112 480
greedy per stage 64 96 96 64 112 432
  • In the vertical layout, BLAKE2b's diagonal step is register renaming, so no data moves inside a pass.
  • Row→column is the one step that truly forces data across lanes: a column G reads rows 0, 2, 4 and 6, which sit in different lanes. This primitive does that move in registers.
  • The load and store columns come from keeping blocks in canonical word order. Storing Argon2's blocks transposed removes them, which leaves 224. That is a follow-up in the password-hashes fork.

Verification

  • simd::tests::u64x8_transpose8_matches_the_index_map:

    • uses 64 distinct words;
    • asserts the fixture is not symmetric, so an identity "transpose" would fail;
    • checks that transposing twice returns the input.

    It passes on native AVX-512 and on pinned x86-64-v3.

  • The NEON parity arm (qemu) and the wasm parity arm (node) pass with the new check 0x310.

  • Disable runs. I broke each backend in turn and confirmed its check fails:

    • AVX-512: changed the chunk selector from 0x88 to 0xDD;
    • AVX2: changed vperm2i128 from 0x20 to 0x31;
    • NEON: swapped vtrn2q for vtrn1q (rc 784);
    • wasm: swapped shuffle <1,3> for <0,2> (rc 784).
  • Full cargo test --lib on native: 2483 passed. clippy -D warnings is clean on native and on v3.

  • Not run: the nightly-simd arm.

🤖 Generated with Claude Code

https://claude.ai/code/session_019HnekoM1EidTwQLS3oFVFm


Generated by Claude Code

…ackends

out[i] lane j == rows[j] lane i. The one physical routing step a lane-wise
consumer cannot express as a coordinate map: argon2's row pass -> column pass
(a column G reads words that live in eight different lanes).

AVX-512: 8 unpack + 16 vshufi64x2 (24). AVX2: four 4x4 unpack/vperm2i128
blocks; off-diagonal blocks swap by destination choice only. NEON / wasm:
32 vtrn1q/vtrn2q or i64x2.shuffle on 2x2 blocks, block placement is
renaming. Scalar / nightly: the index map.

Tests: facade test on 64 distinct words (fixture asserted non-symmetric so
identity fails; transpose is an involution); NEON (qemu) and wasm (node)
parity arms gain check 0x310.

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

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Essentials

Run ID: 16315b19-ad23-4092-92a0-1ec323d2d2a4

📥 Commits

Reviewing files that changed from the base of the PR and between 90cc821 and 873835d.

📒 Files selected for processing (10)
  • .claude/blackboard.md
  • crates/neon-simd-parity/src/main.rs
  • crates/wasm-simd-parity/src/lib.rs
  • src/simd.rs
  • src/simd_avx2.rs
  • src/simd_avx512.rs
  • src/simd_neon.rs
  • src/simd_nightly/u_word_types.rs
  • src/simd_scalar.rs
  • src/simd_wasm.rs
 ________________________________________________________
< Congrats on shipping. Unfortunately, you shipped *it*. >
 --------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

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

@cursor

cursor Bot commented Sep 25, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_3c24c383-cb16-45c8-a83f-78f58e9ab85b)

@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review September 25, 2026 00:10
@AdaWorldAPI
AdaWorldAPI merged commit 5d5d71d into master Sep 25, 2026
25 of 26 checks passed
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