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

Retain all deprecated Bit properties in QPY roundtrip #9525

Merged
merged 9 commits into from
Feb 16, 2023

Conversation

jakelishman
Copy link
Member

@jakelishman jakelishman commented Feb 3, 2023

Summary

A major bugfix for QPY's handling of loose circuit bits in c0ac5fb (gh-9095) caused the deprecated bit properties index and register to be lost after the QPY roundtrip. As far as Terra's data model is concerned, the two circuits would still compare equal after this loss; the output registers would still be equal to the inputs, and bit equality is not considered directly since it general bit instances are not expected to be equal between circuits.

Losing this information caused some downstream issues for the IBM runtime, which was still relying on Bit.index working in some cases, despite it issuing a deprecating warning since Terra 0.17 (April 2021). While this can be corrected downstream, QPY can still do a better job of roundtripping the deprecated information while it is still present.

(Following paragraph obsoleted by b27da19.) The QPY format does not currently store enough information to completely roundtrip this information in cases that some but not all owned bits from a register are present in the circuit. (This partial data is a decent part of the cause of the bugs that gh-9095 fixed.) Since this is just in the support of deprecated functionality that Terra's data model does not even require for circuit equality (QPY's goal), it seems not worth it to produce a new QPY binary format version to store this, when the deprecated properties being removed would obsolete the format again immediately.

Details and comments

The best mitigation for the IBM providers is to fix the use of deprecated functionality in their program runners (I've provided a fix internally). However, this is still something we should fix.

A major bugfix for QPY's handling of loose circuit bits in c0ac5fb
(Qiskitgh-9095) caused the deprecated bit properties `index` and `register` to
be lost after the QPY roundtrip.  As far as Terra's data model is
concerned, the two circuits would still compare equal after this loss;
the output registers would still be equal to the inputs, and bit
equality is not considered directly since it general bit instances are
not expected to be equal between circuits.

Losing this information caused some downstream issues for the IBM
runtime, which was still relying on `Bit.index` working in some cases,
despite it issuing a deprecating warning since Terra 0.17 (April 2021).
While this can be corrected downstream, QPY can still do a better job of
roundtripping the deprecated information while it is still present.

The QPY format does not currently store enough information to
_completely_ roundtrip this information in cases that some but not all
owned bits from a register are present in the circuit.  (This partial
data is a decent part of the cause of the bugs that Qiskitgh-9095 fixed.)
Since this is just in the support of deprecated functionality that
Terra's data model does not even require for circuit equality (QPY's
goal), it seems not worth it to produce a new QPY binary format version
to store this, when the deprecated properties being removed would
obsolete the format again immediately.
@jakelishman jakelishman added stable backport potential The bug might be minimal and/or import enough to be port to stable Changelog: Bugfix Include in the "Fixed" section of the changelog mod: qpy Related to QPY serialization labels Feb 3, 2023
@jakelishman jakelishman requested a review from a team as a code owner February 3, 2023 02:03
@qiskit-bot
Copy link
Collaborator

Thank you for opening a new pull request.

Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient.

While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone.

One or more of the the following people are requested to review this:

@coveralls
Copy link

coveralls commented Feb 3, 2023

Pull Request Test Coverage Report for Build 4196335432

  • 24 of 24 (100.0%) changed or added relevant lines in 1 file are covered.
  • 6 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.03%) to 85.274%

Files with Coverage Reduction New Missed Lines %
qiskit/extensions/quantum_initializer/squ.py 2 80.0%
src/sabre_swap/layer.rs 4 97.32%
Totals Coverage Status
Change from base Build 4196039583: 0.03%
Covered Lines: 67237
Relevant Lines: 78848

💛 - 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.

At a high level this LGTM, we're restoring some information which was missing from the deserialized circuit. Just a couple comments inline.

TBH, I probably should have caught this in review for #9095, a big part of the old very complex/fragile code was to try and recreate registers with standalone bits vs old style registers which owned all their bits as close to the user input as possible. I relied a bit too heavily on the tests to assume we hadn't missed anything and the __eq__ not checking this got us.

qiskit/qpy/binary_io/circuits.py Outdated Show resolved Hide resolved
qiskit/qpy/binary_io/circuits.py Outdated Show resolved Hide resolved
qiskit/qpy/binary_io/circuits.py Outdated Show resolved Hide resolved
This allows complete round-tripping of all the deprecated register+index
information in the `Bit` instances through QPY, restoring us to the
_intended_ behaviour before Qiskitgh-9095.  The behaviour in the dumper before
that did not allow full reconstruction, because some of the information
was lost for bits that were encountered in more than one register.

This fixes the dumper to always output all the indexing information for
all bits, not to use `-1` whenever a bit _is_ in the circuit but has
previously been encountered.  The `standalone` field on a register is
sufficient to tell whether the bits contained in it should have their
"owner" information set; it's not possible (in valid Qiskit code) to
have a register that owns only _some_ of its bits.  To accomodate this,
the register reader now needs to be two-pass.
@jakelishman
Copy link
Member Author

From offline discussions: I was actually able to sort out the logic to completely reconstruct the deprecated register and index information for all bits, without breaking the QPY format. The format already had the spaces for the right information, it just wasn't being stored entirely accurately by the dumper. This PR is now the bugfix that #9095 should have been.

@jakelishman jakelishman changed the title Retain more deprecated Bit properties in QPY roundtrip Retain all deprecated Bit properties in QPY roundtrip Feb 7, 2023
@jakelishman jakelishman added this to the 0.23.2 milestone Feb 14, 2023
@mtreinish mtreinish self-assigned this Feb 14, 2023
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.

Overall this LGTM, I think this all looks correct to me. I had a couple of small inline comments, mostly about adding some more comments on the deserialization side. The logic for this is pretty tricky and I think if we have more inline comments to describe the expected flow will be useful when/if we revisit this block in the future.

qiskit/qpy/binary_io/circuits.py Outdated Show resolved Hide resolved
qiskit/qpy/binary_io/circuits.py Outdated Show resolved Hide resolved
test/qpy_compat/test_qpy.py Show resolved Hide resolved
qiskit/qpy/binary_io/circuits.py Show resolved Hide resolved
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.

LGTM, thanks for all the updates

@mergify mergify bot merged commit b6aba59 into Qiskit:main Feb 16, 2023
mergify bot pushed a commit that referenced this pull request Feb 16, 2023
* Retain more deprecated Bit properties in QPY roundtrip

A major bugfix for QPY's handling of loose circuit bits in c0ac5fb
(gh-9095) caused the deprecated bit properties `index` and `register` to
be lost after the QPY roundtrip.  As far as Terra's data model is
concerned, the two circuits would still compare equal after this loss;
the output registers would still be equal to the inputs, and bit
equality is not considered directly since it general bit instances are
not expected to be equal between circuits.

Losing this information caused some downstream issues for the IBM
runtime, which was still relying on `Bit.index` working in some cases,
despite it issuing a deprecating warning since Terra 0.17 (April 2021).
While this can be corrected downstream, QPY can still do a better job of
roundtripping the deprecated information while it is still present.

The QPY format does not currently store enough information to
_completely_ roundtrip this information in cases that some but not all
owned bits from a register are present in the circuit.  (This partial
data is a decent part of the cause of the bugs that gh-9095 fixed.)
Since this is just in the support of deprecated functionality that
Terra's data model does not even require for circuit equality (QPY's
goal), it seems not worth it to produce a new QPY binary format version
to store this, when the deprecated properties being removed would
obsolete the format again immediately.

* Fix lint

* Correct deprecated bit information in QPY

This allows complete round-tripping of all the deprecated register+index
information in the `Bit` instances through QPY, restoring us to the
_intended_ behaviour before gh-9095.  The behaviour in the dumper before
that did not allow full reconstruction, because some of the information
was lost for bits that were encountered in more than one register.

This fixes the dumper to always output all the indexing information for
all bits, not to use `-1` whenever a bit _is_ in the circuit but has
previously been encountered.  The `standalone` field on a register is
sufficient to tell whether the bits contained in it should have their
"owner" information set; it's not possible (in valid Qiskit code) to
have a register that owns only _some_ of its bits.  To accomodate this,
the register reader now needs to be two-pass.

* Add deprecated-bit checks to backwards compatibility tests

* Rewrite release note

* Improve internal documentation

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit b6aba59)
mergify bot added a commit that referenced this pull request Feb 16, 2023
* Retain more deprecated Bit properties in QPY roundtrip

A major bugfix for QPY's handling of loose circuit bits in c0ac5fb
(gh-9095) caused the deprecated bit properties `index` and `register` to
be lost after the QPY roundtrip.  As far as Terra's data model is
concerned, the two circuits would still compare equal after this loss;
the output registers would still be equal to the inputs, and bit
equality is not considered directly since it general bit instances are
not expected to be equal between circuits.

Losing this information caused some downstream issues for the IBM
runtime, which was still relying on `Bit.index` working in some cases,
despite it issuing a deprecating warning since Terra 0.17 (April 2021).
While this can be corrected downstream, QPY can still do a better job of
roundtripping the deprecated information while it is still present.

The QPY format does not currently store enough information to
_completely_ roundtrip this information in cases that some but not all
owned bits from a register are present in the circuit.  (This partial
data is a decent part of the cause of the bugs that gh-9095 fixed.)
Since this is just in the support of deprecated functionality that
Terra's data model does not even require for circuit equality (QPY's
goal), it seems not worth it to produce a new QPY binary format version
to store this, when the deprecated properties being removed would
obsolete the format again immediately.

* Fix lint

* Correct deprecated bit information in QPY

This allows complete round-tripping of all the deprecated register+index
information in the `Bit` instances through QPY, restoring us to the
_intended_ behaviour before gh-9095.  The behaviour in the dumper before
that did not allow full reconstruction, because some of the information
was lost for bits that were encountered in more than one register.

This fixes the dumper to always output all the indexing information for
all bits, not to use `-1` whenever a bit _is_ in the circuit but has
previously been encountered.  The `standalone` field on a register is
sufficient to tell whether the bits contained in it should have their
"owner" information set; it's not possible (in valid Qiskit code) to
have a register that owns only _some_ of its bits.  To accomodate this,
the register reader now needs to be two-pass.

* Add deprecated-bit checks to backwards compatibility tests

* Rewrite release note

* Improve internal documentation

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit b6aba59)

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
@jakelishman jakelishman deleted the fix-deprecated-bit-qpy-roundtrip branch April 6, 2023 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: Bugfix Include in the "Fixed" section of the changelog mod: qpy Related to QPY serialization stable backport potential The bug might be minimal and/or import enough to be port to stable
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants