Skip to content

Fix transpile() for control flow operations with a Target/BackendV2#8852

Merged
mergify[bot] merged 15 commits into
Qiskit:mainfrom
mtreinish:target-controlflow-ops
Oct 12, 2022
Merged

Fix transpile() for control flow operations with a Target/BackendV2#8852
mergify[bot] merged 15 commits into
Qiskit:mainfrom
mtreinish:target-controlflow-ops

Conversation

@mtreinish
Copy link
Copy Markdown
Member

@mtreinish mtreinish commented Oct 7, 2022

Summary

This commit fixes an issue when compiling with circuits that have control flow operations and are running transpile() with a BackendV2 instance or a custom Target. In these cases the transpile() operation would fail to run because the Target didn't have a provision to recognize a global variable width operation as part of the target. Previously all operations in the target needed to have an instance of an Operation so that the parameters and number of qubits could be verified. Each of these operation instances would be assigned a unique name. But, for control flow operations they're defined over a variable number of qubits and all have the same name (this is a similar problem for gates like mcx too). Not being able to fully represent the control flow operations in a target was preventing running transpile() on a circuit with control flow. This commit fixes this by adding support to the target to represent globally defined operations by passing the class into Target.add_instruction instead of an instance of that class. When the class is received the Target class will treat that operation name and class as always being valid for the target for all qubits and parameters. This can then be used to represent control flow operations in the target and run transpile() with control flow operations.

Details and comments

Fixes #8824

TODO:

This commit fixes an issue when compiling with circuits that have
control flow operations and are running transpile() with a BackendV2
instance or a custom Target. In these cases the transpile() operation
would fail to run because the Target didn't have a provision to
recognize a global variable width operation as part of the target.
Previously all operations in the target needed to have an instance of an
Operation so that the parameters and number of qubits could be verified.
Each of these operation instances would be assigned a unique name. But,
for control flow operations they're defined over a variable number of
qubits and all have the same name (this is a similar problem for gates
like mcx too). Not being able to fully represent the control flow
operations in a target was preventing running transpile() on a circuit
with control flow. This commit fixes this by adding support to the
target to represent globally defined operations by passing the class
into Target.add_instruction instead of an instance of that class. When
the class is received the Target class will treat that operation
name and class as always being valid for the target for all qubits and
parameters. This can then be used to represent control flow operations
in the target and run transpile() with control flow operations.

Fixes Qiskit#8824
@mtreinish mtreinish requested a review from a team as a code owner October 7, 2022 18:07
@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:

  • @Qiskit/terra-core

@mtreinish mtreinish added the stable backport potential Make Mergify open a backport PR to the most recent stable branch on merge. label Oct 7, 2022
@mtreinish mtreinish added this to the 0.22 milestone Oct 7, 2022
@mtreinish
Copy link
Copy Markdown
Member Author

I believe the test failures here are being caused by a bug in transpile() with control flow. I'm seeing a control flow block that has a cx between two qubits that don't have connectivity in the target. Unless, I'm getting the mapping messed up in my head while debugging, I'll keep digging into this and see if I can figure out what's going on, but I'm not sure we have any full path tests with control flow that check the output circuit is valid for the backend (which this PR does) so there could have been a bug that slipped through.

@jakelishman
Copy link
Copy Markdown
Member

The bug looks like it must be in StochasticSwap somewhere - I threw a callback into the test that runs CheckMap on the dag after every stage, and is_swap_mapped never gets set to True.

mtreinish added a commit to mtreinish/qiskit-ibm that referenced this pull request Oct 11, 2022
In Qiskit/qiskit#8852 support is being added to the Target class
for representing globally available variable width operations in order
to support control flow operations. This will be included in the 0.22.0
release. When IBM backends start listing that they support control flow
operations we need to be constructing the Target for the backend with
the control flow operations. This commit adds the necessary handling so
that when a backend lists the control flow operations in the
configuration payload we add the instructions correctly to the Target.
@mtreinish mtreinish changed the title [WIP] Fix transpile() for control flow operations with a Target/BackendV2 Fix transpile() for control flow operations with a Target/BackendV2 Oct 12, 2022
@mtreinish mtreinish mentioned this pull request Oct 12, 2022
5 tasks
Copy link
Copy Markdown
Member

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

This mostly looks good to me, thanks. I had a few questions, but in general the new interface seems sensible to me.

It technically breaks the public API for consumers of the Target class (since the output type signature of Target.instructions and a couple of others change), but I think that might be a necessary evil.

Comment thread qiskit/transpiler/target.py
Comment thread qiskit/transpiler/target.py
Comment thread qiskit/transpiler/target.py Outdated
Comment thread qiskit/transpiler/target.py Outdated
Comment thread qiskit/transpiler/target.py
@mtreinish
Copy link
Copy Markdown
Member Author

It technically breaks the public API for consumers of the Target class (since the output type signature of Target.instructions and a couple of others change), but I think that might be a necessary evil.

I think for Target.instructions the only real difference is that it will return a class instead of an instance for the new support for classes (the None return was still possible before for global defined ideal instances) I'm not sure that's really breaking unless someone is opting into the new feature usage. The coupling map change is more breaking imo, but the old behavior was incorrect though.

Copy link
Copy Markdown
Member

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

Looks good, thanks.

What I meant by the API break was that something that was processing existing Targets could be broken by this - more things than before are now valid Target instances, so someone could pass a new Target (say the new ibm-provider ones) into a method that processes targets, and the method could fail through no fault of its own. I really don't think that's actually happening anywhere in practice, though.

@mergify mergify Bot merged commit ad07847 into Qiskit:main Oct 12, 2022
mergify Bot pushed a commit that referenced this pull request Oct 12, 2022
…8852)

* Fix transpile() for control flow operations with a Target/BackendV2

This commit fixes an issue when compiling with circuits that have
control flow operations and are running transpile() with a BackendV2
instance or a custom Target. In these cases the transpile() operation
would fail to run because the Target didn't have a provision to
recognize a global variable width operation as part of the target.
Previously all operations in the target needed to have an instance of an
Operation so that the parameters and number of qubits could be verified.
Each of these operation instances would be assigned a unique name. But,
for control flow operations they're defined over a variable number of
qubits and all have the same name (this is a similar problem for gates
like mcx too). Not being able to fully represent the control flow
operations in a target was preventing running transpile() on a circuit
with control flow. This commit fixes this by adding support to the
target to represent globally defined operations by passing the class
into Target.add_instruction instead of an instance of that class. When
the class is received the Target class will treat that operation
name and class as always being valid for the target for all qubits and
parameters. This can then be used to represent control flow operations
in the target and run transpile() with control flow operations.

Fixes #8824

* Simplify test slightly

* Add release note

* Add coupling map target test

* Raise if instruction class and properties are both set

* Only return global gates if they exist

* Change UserWarning to a comment

* Revert change to instructions() getter

* Add release note about coupling map api change

* Fix lint and logic bug

* Add back nested while_loop to transpile() test

(cherry picked from commit ad07847)
mergify Bot added a commit that referenced this pull request Oct 13, 2022
…8852) (#8889)

* Fix transpile() for control flow operations with a Target/BackendV2

This commit fixes an issue when compiling with circuits that have
control flow operations and are running transpile() with a BackendV2
instance or a custom Target. In these cases the transpile() operation
would fail to run because the Target didn't have a provision to
recognize a global variable width operation as part of the target.
Previously all operations in the target needed to have an instance of an
Operation so that the parameters and number of qubits could be verified.
Each of these operation instances would be assigned a unique name. But,
for control flow operations they're defined over a variable number of
qubits and all have the same name (this is a similar problem for gates
like mcx too). Not being able to fully represent the control flow
operations in a target was preventing running transpile() on a circuit
with control flow. This commit fixes this by adding support to the
target to represent globally defined operations by passing the class
into Target.add_instruction instead of an instance of that class. When
the class is received the Target class will treat that operation
name and class as always being valid for the target for all qubits and
parameters. This can then be used to represent control flow operations
in the target and run transpile() with control flow operations.

Fixes #8824

* Simplify test slightly

* Add release note

* Add coupling map target test

* Raise if instruction class and properties are both set

* Only return global gates if they exist

* Change UserWarning to a comment

* Revert change to instructions() getter

* Add release note about coupling map api change

* Fix lint and logic bug

* Add back nested while_loop to transpile() test

(cherry picked from commit ad07847)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
mtreinish added a commit to mtreinish/qiskit-core that referenced this pull request Oct 17, 2022
In Qiskit#8852 we added support to the target class for representing variable
width operations by using the class directly instead of an instance. Now
that we have settled on a representation for these types of operations
we can add them to the built in name mapping function (from which they
were previously excluded. This commit adds the built-in variable width
operations to the output of the function and returns just the class
instead of an instance.
kt474 added a commit to Qiskit/qiskit-ibm-provider that referenced this pull request Oct 18, 2022
* Add support for building Targets with control flow operations

In Qiskit/qiskit#8852 support is being added to the Target class
for representing globally available variable width operations in order
to support control flow operations. This will be included in the 0.22.0
release. When IBM backends start listing that they support control flow
operations we need to be constructing the Target for the backend with
the control flow operations. This commit adds the necessary handling so
that when a backend lists the control flow operations in the
configuration payload we add the instructions correctly to the Target.

* Bump qiskit-terra requirement to support change

Co-authored-by: Kevin Tian <kevin.tian@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

Add support for variable width operations to Target

3 participants