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

Fix QPY serialisation of ControlledGate with open controls #8571

Merged
merged 3 commits into from
Aug 18, 2022

Conversation

jakelishman
Copy link
Member

Summary

Previously, an incorrect definition and name would be re-instated on
QPY deserialisation of a ControlledGate instance with open controls.
The base name would include the dynamic _o{ctrl_state} suffix, causing
the suffix to later be duplicated, and the definition would duplicate
the logic that added the open controls. This fixes both by stripping
the suffix on re-read before it is assigned, and serialising only the
"11...1" state definition, since this is what is required and stored by
ControlledGate.

Details and comments

Fix #8549.

This is technically a breaking change in the behaviour of QPY (it changes how something is serialised and deserialised), but it is not a format change. A file created with the previous serialisation behaviour will still load with this new logic, and an older Qiskit will be able to deserialise a circuit dumped with this logic, but in both cases, a ControlledGate with open controls will not be restored to the expected name/definition. There will be no exception, it'll just produce the wrong result, as it did before this patch.

Previously, an incorrect definition and name would be re-instated on
QPY deserialisation of a `ControlledGate` instance with open controls.
The base name would include the dynamic `_o{ctrl_state}` suffix, causing
the suffix to later be duplicated, and the definition would duplicate
the logic that added the open controls.  This fixes both by stripping
the suffix on re-read before it is assigned, and serialising only the
"11...1" state definition, since this is what is required and stored by
`ControlledGate`.
@jakelishman jakelishman added Changelog: Bugfix Include in the "Fixed" section of the changelog mod: qpy Related to QPY serialization labels Aug 17, 2022
@jakelishman jakelishman requested review from a team and nkanazawa1989 as code owners August 17, 2022 17:48
@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 Aug 17, 2022

Pull Request Test Coverage Report for Build 2882009479

  • 8 of 8 (100.0%) changed or added relevant lines in 1 file are covered.
  • 5 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.003%) to 84.048%

Files with Coverage Reduction New Missed Lines %
qiskit/extensions/quantum_initializer/squ.py 2 79.78%
qiskit/pulse/library/waveform.py 3 89.36%
Totals Coverage Status
Change from base Build 2877911364: -0.003%
Covered Lines: 56313
Relevant Lines: 67001

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

LGTM, do you want to add a backwards compat test for this case too? I'm thinking it might be a good idea since the upgrade path on this seems a bit nuanced so we probably don't want it to regress moving forward.

Copy link
Member Author

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

Yeah, the backwards compatibility test sounds good - added in this commit. There's already a test of ctrl_state=0, but unfortunately it's on a CX gate, which doesn't have the same issues because it's a known gate.

@@ -525,6 +549,8 @@ def generate_circuits(version_str=None):
output_circuits["controlled_gates.qpy"] = generate_controlled_gates()
output_circuits["schedule_blocks.qpy"] = generate_schedule_blocks()
output_circuits["pulse_gates.qpy"] = generate_calibrated_circuits()
if version_parts >= (0, 21, 2):
Copy link
Member Author

Choose a reason for hiding this comment

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

I've made this 0.21.2 assuming we might throw this in the backports, but if we're leaving it for 0.22.0, feel free to just modify this line.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that's fine I probably would have just done > (0.21.1) to cover either case but this works fine as I was intending to tag this as stable backport potential

@mtreinish mtreinish added the stable backport potential The bug might be minimal and/or import enough to be port to stable label Aug 18, 2022
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 adding the backwards compat test

@mergify mergify bot merged commit a0964c1 into Qiskit:main Aug 18, 2022
mergify bot pushed a commit that referenced this pull request Aug 18, 2022
* Fix QPY serialisation of ControlledGate with open controls

Previously, an incorrect definition and name would be re-instated on
QPY deserialisation of a `ControlledGate` instance with open controls.
The base name would include the dynamic `_o{ctrl_state}` suffix, causing
the suffix to later be duplicated, and the definition would duplicate
the logic that added the open controls.  This fixes both by stripping
the suffix on re-read before it is assigned, and serialising only the
"11...1" state definition, since this is what is required and stored by
`ControlledGate`.

* Add QPY backwards compatibility test

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit a0964c1)
mergify bot added a commit that referenced this pull request Aug 18, 2022
…8578)

* Fix QPY serialisation of ControlledGate with open controls

Previously, an incorrect definition and name would be re-instated on
QPY deserialisation of a `ControlledGate` instance with open controls.
The base name would include the dynamic `_o{ctrl_state}` suffix, causing
the suffix to later be duplicated, and the definition would duplicate
the logic that added the open controls.  This fixes both by stripping
the suffix on re-read before it is assigned, and serialising only the
"11...1" state definition, since this is what is required and stored by
`ControlledGate`.

* Add QPY backwards compatibility test

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

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
@jakelishman jakelishman deleted the fix-qpy-controlledgate-open-ctrl branch August 19, 2022 12:37
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Oct 17, 2022
This commit fixes a bug in the QPY serialization of ControlledGate
subclasses that defined custom _define() methods. The _define() method
is the typical way to provide a custom definition in Gate classes. While
ControlledGate class provides an alternative interface that handles
custom control states at initialization, but the _define() interface is
still valid even if it doesn't account for this. In Qiskit#8571 we updated the
QPY serialization code to use the _definition() method directly to
correctly handle the open control case. But this fix neglected the case
where people were providing definitions via the mechanism from Gate.
This commit fixes this assumption by ensuring we load the definition
that comes from _define() which will fix the serialization of these
custom subclasses.

Fixes Qiskit#8794
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Oct 17, 2022
This commit fixes a bug in the QPY serialization of ControlledGate
subclasses that defined custom _define() methods. The _define() method
is the typical way to provide a custom definition in Gate classes. While
ControlledGate class provides an alternative interface that handles
custom control states at initialization, but the _define() interface is
still valid even if it doesn't account for this. In Qiskit#8571 we updated the
QPY serialization code to use the _definition() method directly to
correctly handle the open control case. But this fix neglected the case
where people were providing definitions via the mechanism from Gate.
This commit fixes this assumption by ensuring we load the definition
that comes from _define() which will fix the serialization of these
custom subclasses.

Fixes Qiskit#8794
mergify bot added a commit that referenced this pull request Oct 18, 2022
This commit fixes a bug in the QPY serialization of ControlledGate
subclasses that defined custom _define() methods. The _define() method
is the typical way to provide a custom definition in Gate classes. While
ControlledGate class provides an alternative interface that handles
custom control states at initialization, but the _define() interface is
still valid even if it doesn't account for this. In #8571 we updated the
QPY serialization code to use the _definition() method directly to
correctly handle the open control case. But this fix neglected the case
where people were providing definitions via the mechanism from Gate.
This commit fixes this assumption by ensuring we load the definition
that comes from _define() which will fix the serialization of these
custom subclasses.

Fixes #8794

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
mergify bot pushed a commit that referenced this pull request Oct 18, 2022
This commit fixes a bug in the QPY serialization of ControlledGate
subclasses that defined custom _define() methods. The _define() method
is the typical way to provide a custom definition in Gate classes. While
ControlledGate class provides an alternative interface that handles
custom control states at initialization, but the _define() interface is
still valid even if it doesn't account for this. In #8571 we updated the
QPY serialization code to use the _definition() method directly to
correctly handle the open control case. But this fix neglected the case
where people were providing definitions via the mechanism from Gate.
This commit fixes this assumption by ensuring we load the definition
that comes from _define() which will fix the serialization of these
custom subclasses.

Fixes #8794

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 3fb8939)
ajavadia pushed a commit to ajavadia/qiskit that referenced this pull request Oct 18, 2022
This commit fixes a bug in the QPY serialization of ControlledGate
subclasses that defined custom _define() methods. The _define() method
is the typical way to provide a custom definition in Gate classes. While
ControlledGate class provides an alternative interface that handles
custom control states at initialization, but the _define() interface is
still valid even if it doesn't account for this. In Qiskit#8571 we updated the
QPY serialization code to use the _definition() method directly to
correctly handle the open control case. But this fix neglected the case
where people were providing definitions via the mechanism from Gate.
This commit fixes this assumption by ensuring we load the definition
that comes from _define() which will fix the serialization of these
custom subclasses.

Fixes Qiskit#8794

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
mergify bot added a commit that referenced this pull request Oct 18, 2022
This commit fixes a bug in the QPY serialization of ControlledGate
subclasses that defined custom _define() methods. The _define() method
is the typical way to provide a custom definition in Gate classes. While
ControlledGate class provides an alternative interface that handles
custom control states at initialization, but the _define() interface is
still valid even if it doesn't account for this. In #8571 we updated the
QPY serialization code to use the _definition() method directly to
correctly handle the open control case. But this fix neglected the case
where people were providing definitions via the mechanism from Gate.
This commit fixes this assumption by ensuring we load the definition
that comes from _define() which will fix the serialization of these
custom subclasses.

Fixes #8794

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 3fb8939)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
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.

qpy changes names of ControlledGates with non-default ctrl_state
4 participants