Skip to content

fix(hash): spread high-bit keys across buckets in tableau and Pauli-word maps - #267

Merged
MSRudolph merged 2 commits into
mainfrom
fix/slow-fxhash
Oct 23, 2026
Merged

MSRudolph merged 2 commits into
mainfrom
fix/slow-fxhash

Conversation

@MSRudolph

Copy link
Copy Markdown
Contributor

FxHash clusters branch indices and Pauli words that differ mainly in their high bits. This made T gates much slower once extended-stabilizer runs crossed 16,384 coefficients.

This PR uses foldhash for branch-index maps, cached Pauli-word hashes, and the tableau fingerprint fallback on builds without AES. It keeps existing configuration types and uses a fixed seed for reproducible iteration within a build. It also initializes identity-word hashes correctly.

Regression tests cover high-bit key distribution and identity-word map lookups. One Lindblad test now tolerates tiny rounding differences caused by the changed summation order.

Representative timings on an Apple M4 Pro, release builds, medians:

Just the hash map

Case main this PR
Branch map for one T gate, 32k coefficients, 64 qubits (usize) 153.7 ms 0.20 ms
Same, 128 qubits (u128) 154.4 ms 0.17 ms
Same, 256 qubits (U256) 147.4 ms 0.35 ms
Same, 2048 qubits (U2048) 227.2 ms 2.2 ms
Insert the 96k words of a 64-qubit TFIM run into a PauliSum map 2.53 ms 1.20 ms
Same, 128 qubits (201k words) 5.22 ms 2.68 ms

Full simulations

Simulation Before After
Extended stabilizer, 64 qubits, 65k coefficients (rayon) 900 ms 3 ms
TFIM Pauli propagation, 64 qubits 763 ms 459 ms
TFIM Pauli propagation, 128 qubits 3,696 ms 2,089 ms
Noisy magic-state distillation mixture 770 ms 772 ms

TFIM term counts and noisy-distillation branch probabilities match main exactly. Workspace tests, tableau tests with rayon, Clippy, and formatting checks pass.

@MSRudolph
MSRudolph requested review from Roger-luo and david-pl and a balanced review from Copilot October 23, 2026 09:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@MSRudolph

MSRudolph commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

The peripheral Lindblad test change is because it accidentally relied on insertion order.

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-23 11:34 UTC

@david-pl david-pl added the category: breaking change Category: breaking changes or proposed changes to APIs. label Oct 23, 2026

@Roger-luo Roger-luo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any public user interface breaking in this PR, so I think it's totally fine.

Comment thread crates/ppvm-traits/src/traits/hash.rs Outdated

/// Fast hasher for internal maps and word hashes, with a fixed seed.
/// Iteration is reproducible for the same build and insertion order.
pub type FastBuildHasher = foldhash::fast::FixedState;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we just call it FoldBuildHasher? Fast is quite general, the convention here should be transparent about what downstream hasher we are using.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 342e323

@david-pl david-pl removed the category: breaking change Category: breaking changes or proposed changes to APIs. label Oct 23, 2026
Copilot AI balanced review requested due to automatic review settings October 23, 2026 11:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@MSRudolph
MSRudolph enabled auto-merge (squash) October 23, 2026 11:30
@MSRudolph
MSRudolph merged commit 7e653d4 into main Oct 23, 2026
14 checks passed
@MSRudolph
MSRudolph deleted the fix/slow-fxhash branch October 23, 2026 11:34
@github-actions github-actions Bot mentioned this pull request Oct 23, 2026
david-pl added a commit that referenced this pull request Oct 23, 2026
`GeneralizedTableau::rotate_2` (RXX / RYY / RZZ) accumulated the new
coefficients in a `std::collections::HashMap`. Its SipHash hasher is
seeded randomly per process, so the order in which coefficients were
written back into the tableau differed from run to run.

This switches it to `ppvm_traits::FoldHashMap`, the fixed-seed hasher
the other tableau coefficient maps have used since #267. That makes the
post-rotation coefficient order reproducible within a build, and
foldhash is also cheaper than SipHash for integer keys.

`cargo test -p ppvm-tableau` passes with and without `--features rayon`,
and clippy is clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
david-pl pushed a commit that referenced this pull request Oct 23, 2026
## 🤖 New release

* `ppvm-traits`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-pauli-word`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-pauli-sum`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-sym`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-tableau`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `stim-parser`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-stim`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-tableau-sum`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `vihaco-circuit-isa`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-vihaco`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-tui`: 0.1.0 -> 0.1.1 (✓ API compatible changes)
* `ppvm-cli`: 0.1.0 -> 0.1.1

<details><summary><i><b>Changelog</b></i></summary><p>












## `ppvm-cli`

<blockquote>

##
[0.1.1](v0.1.0...v0.1.1)
- 2026-10-23

### Fixed

- *(hash)* spread high-bit keys across buckets in tableau and Pauli-word
maps ([#267](#267))
- *(tableau)* use FoldHashMap for two-qubit rotation coefficients
([#268](#268))

### Other

- add crates.io READMEs for the published crates
([#265](#265))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

4 participants