Skip to content

Use a single type alias for indexmap and indexset to enforce hasher#16130

Open
mtreinish wants to merge 8 commits intoQiskit:mainfrom
mtreinish:common-indexmap
Open

Use a single type alias for indexmap and indexset to enforce hasher#16130
mtreinish wants to merge 8 commits intoQiskit:mainfrom
mtreinish:common-indexmap

Conversation

@mtreinish
Copy link
Copy Markdown
Member

Building off of #15920 which moved our hasher for IndexMap usage to be
foldhash this moves to having a common type alias for IndexMap and
IndexSet that has the hasher set. All the internal usage of IndexMap and
IndexSet are updated to use this new alias instead which removes the
boiler plate around dealing with initializing the hasher for the most
part, the only exception is when using with_capacity_and_hasher()
there is no method to create an empty object with a capacity
preallocated and the hasher is initialized from the generic type. To
enforce that we're using the correct hasher for all indexmap usage the
clippy rules are updated to disallow the indexmap::IndexMap and
indexmap::IndexSet types directly. This means that after this commit all
indexmap usage with be forced by clippy to leverage our standard pattern
using foldhash. The advantage is if we ever need to change the default
hasher again in the future we only need to update one central place
(and the places using with_capacity_and_hasher).

This PR is based on top of #15920 and will need to be rebased after that is merged. In the meantime you can view the contents of just this PR by looking at the PR branch's HEAD commit:

12f7ed5

AI/LLM disclosure

  • I didn't use LLM tooling, or only used it privately.
  • I used the following tool to help write this PR description:
  • I used the following tool to generate or modify code:

This commit switches our use of ahash as the hashing algorithm for
IndexMap to use foldhash instead. This mirrors the change that was done
in hashbrown for the default hashing algorithm in its hashmap. Foldhash
promises faster hashing than ahash with similar quality tradeoffs. Since
IndexSet/IndexMap defaults to using the stdlib SipHash algorithm which
is not good for performance we need to set a custom hash algorithm to
maintain good performance. Since we use an IndexSet for the interners
saving a small amount of time per lookup here is especially important.

The only place that ahash is retained is for DAGNode in Python. The
usage was specific to how ahash worked and switching it to an analogous
foldhash interface caused test failures. As the performance is not
critical for this code path as it's only used by the Python API for
accessing the DAG and it's already not a performant path saving
nanoseconds on hashing doesn't matter. There is probably an alternative
API in foldhash we could use, but it didn't seem critical to figure out.
Building off of Qiskit#15920 which moved our hasher for IndexMap usage to be
foldhash this moves to having a common type alias for IndexMap and
IndexSet that has the hasher set. All the internal usage of IndexMap and
IndexSet are updated to use this new alias instead which removes the
boiler plate around dealing with initializing the hasher for the most
part, the only exception is when using `with_capacity_and_hasher()`
there is no method to create an empty object with a capacity
preallocated and the hasher is initialized from the generic type. To
enforce that we're using the correct hasher for all indexmap usage the
clippy rules are updated to disallow the indexmap::IndexMap and
indexmap::IndexSet types directly. This means that after this commit all
indexmap usage with be forced by clippy to leverage our standard pattern
using foldhash. The advantage is if we ever need to change the default
hasher again in the future we only need to update one central place
(and the places using with_capacity_and_hasher).
@mtreinish mtreinish added on hold Can not fix yet Changelog: None Do not include in the GitHub Release changelog. Rust This PR or issue is related to Rust code in the repository labels May 4, 2026
@qiskit-bot
Copy link
Copy Markdown
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core
  • @mtreinish

@mtreinish mtreinish requested a review from a team as a code owner May 4, 2026 16:06
@mtreinish mtreinish requested a review from alexanderivrii May 4, 2026 16:06
@coveralls
Copy link
Copy Markdown

Coverage Report for CI Build 25329395775

Coverage increased (+0.02%) to 87.576%

Details

  • Coverage increased (+0.02%) from the base build.
  • Patch coverage: 9 uncovered changes across 5 files (108 of 117 lines covered, 92.31%).
  • 4 coverage regressions across 2 files.

Uncovered Changes

File Changed Covered %
crates/bindgen-c/src/lint.rs 3 0 0.0%
crates/transpiler/src/equivalence.rs 15 13 86.67%
crates/transpiler/src/passes/constrained_reschedule.rs 2 0 0.0%
crates/synthesis/src/evolution/suzuki_trotter.rs 1 0 0.0%
crates/transpiler/src/passes/basis_translator/compose_transforms.rs 15 14 93.33%

Coverage Regressions

4 previously-covered lines in 2 files lost coverage.

File Lines Losing Coverage Coverage
crates/qasm2/src/lex.rs 3 92.29%
crates/circuit/src/parameter/parameter_expression.rs 1 90.53%

Coverage Stats

Coverage Status
Relevant Lines: 121800
Covered Lines: 106667
Line Coverage: 87.58%
Coverage Strength: 965467.14 hits per line

💛 - Coveralls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Changelog: None Do not include in the GitHub Release changelog. on hold Can not fix yet Rust This PR or issue is related to Rust code in the repository

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants