Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a gate name interner to avoid duplicating String in the Target #12917

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

raynelfss
Copy link
Contributor

Summary

The current implementation of Target in Rust, performs a lot of cloning when adding an instruction to the Target. These commits allow it to keep one copy of these String instances and have copy-able (usize) values represent them in the other structures of the target

Details and comments

The following commits add an interner which enable us to avoid multiple cloning of attributes with repeated use in multiple mapping structures within the target; In this case, with the gate names.

These changes are made along the following other changes:

  • Remove variable_operation_class, use enum nature to discriminate.
  • Hide gate_name_map from Python, use operation_from_name.
  • Other small tweaks and fixes.

Known issues:

Nothing so far, make sure to bring up during review.

… instances.

- Remove `variable_operation_class`, use enum nature to discriminate.
- Hide `gate_name_map` from Python, use `operation_from_name`.
- Other small tweaks and fixes.
@raynelfss raynelfss requested a review from a team as a code owner August 7, 2024 20:08
@qiskit-bot
Copy link
Collaborator

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

  • @Qiskit/terra-core
  • @kevinhartman
  • @mtreinish

@coveralls
Copy link

coveralls commented Aug 7, 2024

Pull Request Test Coverage Report for Build 10928640225

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 157 of 184 (85.33%) changed or added relevant lines in 2 files are covered.
  • 190 unchanged lines in 12 files lost coverage.
  • Overall coverage increased (+0.5%) to 88.828%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/transpiler/target.py 0 1 0.0%
crates/accelerate/src/target_transpiler/mod.rs 157 183 85.79%
Files with Coverage Reduction New Missed Lines %
qiskit/pulse/instructions/directives.py 1 97.22%
qiskit/pulse/transforms/alignments.py 1 96.45%
crates/qasm2/src/lex.rs 1 92.98%
crates/accelerate/src/two_qubit_decompose.rs 1 91.45%
qiskit/circuit/library/pauli_evolution.py 2 96.15%
qiskit/primitives/containers/data_bin.py 2 96.36%
qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py 3 93.98%
crates/accelerate/src/target_transpiler/mod.rs 20 80.05%
qiskit/pulse/builder.py 25 89.11%
qiskit/quantum_info/operators/symplectic/pauli.py 29 85.98%
Totals Coverage Status
Change from base Build 10919208944: 0.5%
Covered Lines: 73571
Relevant Lines: 82824

💛 - Coveralls

Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

I'm glad to see this, I meant to open an issue from: #12292 (comment) but it's good you beat me to that. I haven't had a chance to review the code in depth yet, but I had a high level question inline off the top.

qarg_gate_map: NullableIndexMap<Qargs, Option<HashSet<String>>>,
non_global_strict_basis: Option<Vec<String>>,
non_global_basis: Option<Vec<String>>,
gate_name_map: IndexMap<usize, TargetOperation, RandomState>,
Copy link
Member

Choose a reason for hiding this comment

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

One small question here, is there a reason we the full width of a usize? It is natural because that's the index type for IndexSet, but I'm pretty confident we don't the full 64 bit (or 32 bit on those platform) address space. Realistically I feel like we could get away with a u8 because it seems unlikely for a target to support more than >255 gates at once. If we wanted to be a bit conservative we could use a u16, there is almost no possibility of a target having over 65k gates names it.

Copy link
Member

Choose a reason for hiding this comment

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

I can imagine a world with >255 operation names, if we had something like multiple fractional 2q gates (heterogeneous arch) exposed both continuously and with various precisely calibrated points on the parametrisation.

Copy link
Member

Choose a reason for hiding this comment

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

255 is more than it sounds like. I would be surprised if anyone spent the time to calibrate all those different variants even on a far future system. But I also agree with you that it is within the realm of plausibility, however u16::MAX is definitely sufficiently large though so I think using a u16 newtype here for the target string index would make a lot of sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes sense. Although the default indexing unit for IndexSet is mainly usize, I see how it could help to use a smaller datatype to store these indices in.

@jakelishman
Copy link
Member

Ray: I don't know your exact plans for the type here, but I think you should be able to create an Interner<str> now from the existing Interner, and it'll fulfil (almost) everything you need.

@jakelishman
Copy link
Member

Then all the magic u16s will become Interned<str> - that's a u32 internally, but it's a) possible to make Interner and Interned more generic so they use u16 instead and b) probably not going to matter for the Target anyway (personally I'd probably just use u32).

@raynelfss
Copy link
Contributor Author

Hey @jakelishman yes I'm currently playing with it. However, there are certain traits that I will need to implement beforehand. Will get back to you on this.

@raynelfss raynelfss added the on hold Can not fix yet label Sep 19, 2024
@jakelishman
Copy link
Member

The concept of the existing Interner is still based around index-set lookups, just like your new one is, so I'd be surprised if there's too much work needed to make the existing one do everything you need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
on hold Can not fix yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants