-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Move Bit
and Register
to live in Rust space
#13860
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
- Use `macro_rules!` to create `Bit` and `Registers`.
- Add `new_owned` method for `BitInfo`.
Pull Request Test Coverage Report for Build 13728587689Details
💛 - Coveralls |
- Rebalance currently available api to allow for superclasses `Bit` and `Register` to also live in Rust. - Remove: `ShareableBit` triat and structs that implement it. Replace them with new structs.
- Add prefix class attribute for python `Register` instances.
- Add `BitExtraInfo` as a soft identifier for `BitInfo`, can be null to identify a `Bit`. - Add `RegisterInfo::get` method to retrieve the information of a `Bit`. - Have the rust registers own their counters instead of having them be Python exclusive. - Make subclassing of `Regster` and `Bit` a bit more effective by helping the subclasses inherit most methods.
15ee40d
to
1d112c5
Compare
…GCircuit`. - Modify `BitData` to accept an extra generic value specifying a "sharable" object type that can also be turned into a `PyObject` to allow for compatibility with `Var`. - Rename `BitAsKey` to `VarAsKey` as it is currently only used for `Var` instances. - Modify methods in `CommutationChecker` and `GateDirection` passes to use the newer methods. - Other tweaks and fixes.
…bit`. - Remove imports of `QUBIT` and `CLBIT` from `DAGCircuit` and `CircuitData`.
- Discarded old equality and hashing methods for `PyBit` and `PyRegister`. - Fix `replace_bits` to accept any iterator over `Qubits` and `Clbits` from Python. - Add `is_empty` methods to Register data, wherever `len` is available. - Add additional parsing during creation of `Register` to more closely match previous behavior. - Modify `Bit` tests due to mocking no longer operating correctly.
- Add method `register` to `BitData` to better represent a register reference in an owned bit.
- Add missing quotation marks in `Register` repr().
- Bits and registers that live in Rust are not guaranteed to pass the `is` equality check in Python. - Restore type checking in `DAGCircuit` when adding bits.
- `Bits` should retain their hash value upon deserialization to avoid incorrect retrievals via hash or indexing. Fixed by implementing correct `__reduce__` method in `PyBit`, `PyClbit`, and `PyQubit`. - Replace `__getnnewargs__` methods with `__reduce__` for more versatile serialization. - Extend `SliceOrVec` to include a method that allows a vec with negative indices to correctly iterate based on a provided size. - Modify `FullAncillaAllocation` to not replace the `QuantumRegister` prefix. - Add `instances_count` getter attribute to all registers. - `is` comparisons are no longer guaranteed to work between bits and registers. So some tests have been modified to reflect that. - When `apply_operation` in the `DAGCircuit` receives a clbit in place of a qubit and viceversa, it will throw a type error, not a Key error. This is handled by PyO3 directly during extraction.
14e1541
to
25c5fbf
Compare
- Create `RegisterData` struct which, similarly to how `BitData` works, stores the registers and allows to access them by key, in this case by name or index. - Tweak `CircuitData` and `QuantumCircuit` api to allow for access of registers from within `CircuitData`. - Add `qubit_indices` and `clbit_indices` structs to keep track of the locations of bits and registers within the circuit. - Modify `circuit_to_dag` to obtain the registers directly from `CircuitData`. - Modify `BlueprintCircuit` to rely on `CircuitData` to access `QuantumRegister` instances. - Add setters and getters for registers. - Modify `circuit_to_instruction` to bring over the registers into the definition of the `Instruction`. - Add `contains` method to `BitData`. - Add rust native `BitLocations` that can be converted to a `Python` version if needed.
25c5fbf
to
a578bf6
Compare
- Implemented `RegisterData` within the `DAGCircuit`. - Modified methods of the `DAGCircuit` to utilize new native structures wherever possible. - Modify `RegisterData` to not have a `description` attribute, and use an `IndexMap` to preserve insertion order of the registers. - Use native initializers for Registers throughout the crate. - Use native bits in initializer methods for `QuantumCircuit` and `ClassicalCircuit` instead of `BitData`. - Modify additional `is` checks from tests where not needed. - Modify `test_gate_definitions` to create owning registers when testing for definitions from the `EquivalenceLibrary`.
5 tasks
- Fix `remove` method to work more efficiently and add `remove_registers` for multiple removals. - Store index mapping between register name and `RegisterIndex<u32>` which is copyable.
mtreinish
approved these changes
Mar 7, 2025
kevinhartman
approved these changes
Mar 7, 2025
mtreinish
added a commit
to mtreinish/qiskit-core
that referenced
this pull request
Mar 10, 2025
In preparation for providing a C API for building and interacting with circuits this commit removes the required Python component from the circuit construction APIs on CircuitData. After Qiskit#13860 the only use case of Python in the circuit constructor is to manipulate a ParameterExpression global phase as ParameterExpression is still a Python only construct. This moves to using Python::with_gil() in those places only when it's needed. This gives us a path for building a circuit without the Python interpreter for the C API.
raynelfss
added a commit
to raynelfss/qiskit
that referenced
this pull request
Mar 11, 2025
In an oversight after Qiskit#13860, when switching to use the pyo3 friendly `BitLocations` which is not an instance of `namedtuple` we did not extend it to include sequence methods `__getitem__` and `__len__`, which results in breaking api changes. The following commits add those methods to `BitLocations` and also labels the class correctly as a `sequence` in PyO3.
raynelfss
added a commit
to raynelfss/qiskit
that referenced
this pull request
Mar 12, 2025
Prior implementations would replace the Register's prefix attribute inplace which is an unsafe operation. The following commits add a secure path for a provisional replacement of a register's prefix name to fix changed unsafe behavior from Qiskit#13860.
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 12, 2025
) * Add: `__getitem__` and other attributes to `BitLocations` In an oversight after #13860, when switching to use the pyo3 friendly `BitLocations` which is not an instance of `namedtuple` we did not extend it to include sequence methods `__getitem__` and `__len__`, which results in breaking api changes. The following commits add those methods to `BitLocations` and also labels the class correctly as a `sequence` in PyO3. * Fix: Address review comments * Fix: More formatting issues in tests * Apply suggestions from code review Co-authored-by: Matthew Treinish <mtreinish@kortar.org> --------- Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
mergify bot
pushed a commit
that referenced
this pull request
Mar 12, 2025
) * Add: `__getitem__` and other attributes to `BitLocations` In an oversight after #13860, when switching to use the pyo3 friendly `BitLocations` which is not an instance of `namedtuple` we did not extend it to include sequence methods `__getitem__` and `__len__`, which results in breaking api changes. The following commits add those methods to `BitLocations` and also labels the class correctly as a `sequence` in PyO3. * Fix: Address review comments * Fix: More formatting issues in tests * Apply suggestions from code review Co-authored-by: Matthew Treinish <mtreinish@kortar.org> --------- Co-authored-by: Matthew Treinish <mtreinish@kortar.org> (cherry picked from commit 3a80a81)
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 12, 2025
) (#14008) * Add: `__getitem__` and other attributes to `BitLocations` In an oversight after #13860, when switching to use the pyo3 friendly `BitLocations` which is not an instance of `namedtuple` we did not extend it to include sequence methods `__getitem__` and `__len__`, which results in breaking api changes. The following commits add those methods to `BitLocations` and also labels the class correctly as a `sequence` in PyO3. * Fix: Address review comments * Fix: More formatting issues in tests * Apply suggestions from code review Co-authored-by: Matthew Treinish <mtreinish@kortar.org> --------- Co-authored-by: Matthew Treinish <mtreinish@kortar.org> (cherry picked from commit 3a80a81) Co-authored-by: Raynel Sanchez <87539502+raynelfss@users.noreply.github.com>
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 14, 2025
* Remove Python dependency from circuit construction In preparation for providing a C API for building and interacting with circuits this commit removes the required Python component from the circuit construction APIs on CircuitData. After #13860 the only use case of Python in the circuit constructor is to manipulate a ParameterExpression global phase as ParameterExpression is still a Python only construct. This moves to using Python::with_gil() in those places only when it's needed. This gives us a path for building a circuit without the Python interpreter for the C API. * Remove with_gil for calling extend() in new()
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 18, 2025
* FIx: Create an internal path for custom prefixes in registers. Prior implementations would replace the Register's prefix attribute inplace which is an unsafe operation. The following commits add a secure path for a provisional replacement of a register's prefix name to fix changed unsafe behavior from #13860. * Fix: Address review comments - Add test-case * Apply suggestions from code review Co-authored-by: Kevin Hartman <kevin@hart.mn> * Fix: Address more review comments * Fix: Lint error * Update test/python/circuit/test_circuit_operations.py Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --------- Co-authored-by: Kevin Hartman <kevin@hart.mn> Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
mergify bot
pushed a commit
that referenced
this pull request
Mar 18, 2025
* FIx: Create an internal path for custom prefixes in registers. Prior implementations would replace the Register's prefix attribute inplace which is an unsafe operation. The following commits add a secure path for a provisional replacement of a register's prefix name to fix changed unsafe behavior from #13860. * Fix: Address review comments - Add test-case * Apply suggestions from code review Co-authored-by: Kevin Hartman <kevin@hart.mn> * Fix: Address more review comments * Fix: Lint error * Update test/python/circuit/test_circuit_operations.py Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --------- Co-authored-by: Kevin Hartman <kevin@hart.mn> Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> (cherry picked from commit 56a16ab)
github-merge-queue bot
pushed a commit
that referenced
this pull request
Mar 18, 2025
…) (#14048) * FIx: Create an internal path for custom prefixes in registers. Prior implementations would replace the Register's prefix attribute inplace which is an unsafe operation. The following commits add a secure path for a provisional replacement of a register's prefix name to fix changed unsafe behavior from #13860. * Fix: Address review comments - Add test-case * Apply suggestions from code review Co-authored-by: Kevin Hartman <kevin@hart.mn> * Fix: Address more review comments * Fix: Lint error * Update test/python/circuit/test_circuit_operations.py Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --------- Co-authored-by: Kevin Hartman <kevin@hart.mn> Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> (cherry picked from commit 56a16ab) Co-authored-by: Raynel Sanchez <87539502+raynelfss@users.noreply.github.com>
raynelfss
added a commit
to raynelfss/qiskit
that referenced
this pull request
Mar 20, 2025
…kit#13997) * Add: `__getitem__` and other attributes to `BitLocations` In an oversight after Qiskit#13860, when switching to use the pyo3 friendly `BitLocations` which is not an instance of `namedtuple` we did not extend it to include sequence methods `__getitem__` and `__len__`, which results in breaking api changes. The following commits add those methods to `BitLocations` and also labels the class correctly as a `sequence` in PyO3. * Fix: Address review comments * Fix: More formatting issues in tests * Apply suggestions from code review Co-authored-by: Matthew Treinish <mtreinish@kortar.org> --------- Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
raynelfss
pushed a commit
to raynelfss/qiskit
that referenced
this pull request
Mar 20, 2025
* Remove Python dependency from circuit construction In preparation for providing a C API for building and interacting with circuits this commit removes the required Python component from the circuit construction APIs on CircuitData. After Qiskit#13860 the only use case of Python in the circuit constructor is to manipulate a ParameterExpression global phase as ParameterExpression is still a Python only construct. This moves to using Python::with_gil() in those places only when it's needed. This gives us a path for building a circuit without the Python interpreter for the C API. * Remove with_gil for calling extend() in new()
raynelfss
added a commit
to raynelfss/qiskit
that referenced
this pull request
Mar 20, 2025
…it#14005) * FIx: Create an internal path for custom prefixes in registers. Prior implementations would replace the Register's prefix attribute inplace which is an unsafe operation. The following commits add a secure path for a provisional replacement of a register's prefix name to fix changed unsafe behavior from Qiskit#13860. * Fix: Address review comments - Add test-case * Apply suggestions from code review Co-authored-by: Kevin Hartman <kevin@hart.mn> * Fix: Address more review comments * Fix: Lint error * Update test/python/circuit/test_circuit_operations.py Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> --------- Co-authored-by: Kevin Hartman <kevin@hart.mn> Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
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 changelog
mod: circuit
Related to the core of the `QuantumCircuit` class or the circuit library
priority: high
Rust
This PR or issue is related to Rust code in the repository
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
The following commits finally bring
Bits
andRegisters
entirely to Rust by performing a couple of tasks:Bit
(a.k.a.ShareableQubit
andShareableClbit
) andRegister
(a.k.a.QuantumRegister
andClassicalRegister
) and move their python counterparts to be managed by rust PyO3.DAGCircuit
andCircuitData
.RegisterData
andBitLocator
to represent the layout of bits/registers in the circuit.All these changes supersede #13686.
Details and comments
As we move more of our core data model to Rust, the main drawback that we've still had is needing to use Python space to create bits and registers. Although simple on the outside, the
Bit
andRegister
structures in Python can be quite challenging due to cross referencing that can happen between each type to the other (Bit._register
<->Register[i]
] which is not as easy to replicate in Rust space.With the following commits we aim to move the representation of
Bits
andRegisters
to Rust in which the behavior is more similar to that of Python and allows us to share instances between circuits, rather than having the circuit have complete ownership of the bits it contains (which is the reason for preferring this over #13686).Additions
Bit representation:
To represent a
Qubit
orClbit
in Rust, we have a couple of identifiers:Qubit
orClbit
which is an index that the circuit can locally refer to when using a bit.Bit
:ShareableQubit
which represents a global bit.ShareableClbit
the classical counterpart to theShareableQubit
.The base structure for a
Bit
in Rust, calledBitInfo
describes a global bit as being one of two things:Owned
where the bit is owned by a register.Anonymous
where the bit is independent, containing its own unique ID.Each of these
Bits
also has an extra property calledBitExtraInfo
that acts as an identifier, and contains any extra information aBit
of a specific type should have. In the case ofShareableQubit
whether the instance is an ancilla or not.Python:
PyBit
,PyQubit
,PyClbit
andPyAncillaQubit
) have similar behavior and inheritance models as the originals, but should not be subclassed any further as it is no longer supported. See Deprecate subclassing ofRegister
andBit
#13841.is()
checks due to conversions in PyO3 not taking on the same addresses.IntoPyObject<'_>
so that they can be successfully converted and extracted from their Python counterparts.Register representation:
To represent a
QuantumRegister
orClassicalRegister
in Rust, we can use the rust native counterparts of the same name:RegisterInfo
which classifies them into two categories:Owning
: which owns its bits, can generate them as needed. All of its bits areOwned
.Alias
: A register that acts as a collection of bits independent from their type.RegisterData
struct.Python:
Register
andBit
#13841. They may also not be compared using is(), and the native implementations can be converted to and from Python using the `IntoPyObject<'_> trait.CircuitData
CircuitData has been upgraded to contain registers, this is how it was achieved.
RegisterData
was created just to save all of the registers stored in theCircuitData
instance.PyDict
to allow for a faster visit path from Python.BitLocator
it is essentially a wrapper around anIndexMap
and emulates the behavior ofQuantumCircuit._{cl, qu}bit_indices
.RegisterData
, it also contains a cachedPyDict
to enable faster access from python.{q,c}bit_argument_conversions
methods inQuantumCircuit
which perform mappings with native bit types.DAGCircuit
The DAGCircuit now uses
RegisterData
andBitLocator
in the same way they are used forCircuitData
, getting rid of the manyPyDict
objects being stored within. Said additions removed the need of mostpy
tokens previously needed to modify the circuit's bits and registers.Questions and Comments
Feel free to leave a review/comment addressing any questions you may have. 🚀
Co-authored-by: Jake Lishman jake.lishman@ibm.com