-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Avoid operator creation in transpiler #12826
Conversation
One or more of the following people are relevant to this code:
|
This removes very nearly all of the use of `DAGOpNode.op` in the default transpiler paths. The sole exception is in `InverseCancellation`, which currently would involve some quite awkward gymnastics for little near-term benefit. The pass should move fully to Rust soon, making it not worth the effort. Most of the tricks here involve using the knowledge that most operations will involve only Rust-space standard gates, and that these cannot be control-flow operations.
d605106
to
991263a
Compare
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 10184959106Details
💛 - Coveralls |
There was a problem hiding this 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'm happy to wrap up this thread of workarounds before we start migrating passes to rust (which will be doing essentially this but without the language barrier). Just one inline comment but something that's applicable to a bunch of places, basically we can use the name of a control flow op instead of an isinstance
check to defer the op creation until we actually use it. Although as those are always PyInstruction
it doesn't really matter from a performance perspective as we always have a cached pyobject at that point. So I'm fine merging this as-is if you don't think it's important. Feel free to just enqueue this for merge in that case.
@@ -37,7 +37,7 @@ class MultiQEncountered(Exception): | |||
|
|||
def _visit(dag, weight, wire_map): | |||
for node in dag.op_nodes(include_directives=False): | |||
if isinstance(node.op, ControlFlowOp): | |||
if node.is_control_flow(): | |||
if isinstance(node.op, ForLoopOp): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could avoid the op usage here too if you did:
if isinstance(node.op, ForLoopOp): | |
if node.name == "for_loop": |
* Avoid operator creation in transpiler This removes very nearly all of the use of `DAGOpNode.op` in the default transpiler paths. The sole exception is in `InverseCancellation`, which currently would involve some quite awkward gymnastics for little near-term benefit. The pass should move fully to Rust soon, making it not worth the effort. Most of the tricks here involve using the knowledge that most operations will involve only Rust-space standard gates, and that these cannot be control-flow operations. * Fix `HighLevelSynthesis` fast path --------- Co-authored-by: Matthew Treinish <[email protected]> (cherry picked from commit 0afb06e)
* Avoid operator creation in transpiler This removes very nearly all of the use of `DAGOpNode.op` in the default transpiler paths. The sole exception is in `InverseCancellation`, which currently would involve some quite awkward gymnastics for little near-term benefit. The pass should move fully to Rust soon, making it not worth the effort. Most of the tricks here involve using the knowledge that most operations will involve only Rust-space standard gates, and that these cannot be control-flow operations. * Fix `HighLevelSynthesis` fast path --------- Co-authored-by: Matthew Treinish <[email protected]> (cherry picked from commit 0afb06e) Co-authored-by: Jake Lishman <[email protected]>
* Avoid operator creation in transpiler This removes very nearly all of the use of `DAGOpNode.op` in the default transpiler paths. The sole exception is in `InverseCancellation`, which currently would involve some quite awkward gymnastics for little near-term benefit. The pass should move fully to Rust soon, making it not worth the effort. Most of the tricks here involve using the knowledge that most operations will involve only Rust-space standard gates, and that these cannot be control-flow operations. * Fix `HighLevelSynthesis` fast path --------- Co-authored-by: Matthew Treinish <[email protected]>
Summary
This removes very nearly all of the use of
DAGOpNode.op
in the default transpiler paths. The sole exception is inInverseCancellation
, which currently would involve some quite awkward gymnastics for little near-term benefit. The pass should move fully to Rust soon, making it not worth the effort.Most of the tricks here involve using the knowledge that most operations will involve only Rust-space standard gates, and that these cannot be control-flow operations.
Details and comments
This always includes a reno for a couple of the new methods added to
DAGOpNode
andCircuitInstruction
.I measured this as being ~25% faster for some toy workloads at transpilation levels 0 and 1, probably mostly driven by the new methods letting us avoid a lot of
isinstance
checks in most cases.