Skip to content

Fix QPY serialisation of ControlledGate with open controls#8571

Merged
mergify[bot] merged 3 commits into
Qiskit:mainfrom
jakelishman:fix-qpy-controlledgate-open-ctrl
Aug 18, 2022
Merged

Fix QPY serialisation of ControlledGate with open controls#8571
mergify[bot] merged 3 commits into
Qiskit:mainfrom
jakelishman:fix-qpy-controlledgate-open-ctrl

Conversation

@jakelishman
Copy link
Copy Markdown
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: Fixed Add a "Fixed" entry in the GitHub Release 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
Copy Markdown
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
Copy Markdown

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
Copy Markdown
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
Copy Markdown
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.

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
Copy Markdown
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
Copy Markdown
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 Make Mergify open a backport PR to the most recent stable branch on merge. label Aug 18, 2022
Copy link
Copy Markdown
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 added 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 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)
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: Fixed Add a "Fixed" entry in the GitHub Release changelog. mod: qpy Related to QPY serialization stable backport potential Make Mergify open a backport PR to the most recent stable branch on merge.

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