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

Speed up synthesis passes when there is nothing to synthesize #10788

Merged
merged 4 commits into from
Sep 7, 2023

Conversation

mtreinish
Copy link
Member

@mtreinish mtreinish commented Sep 6, 2023

Summary

This commit makes a small optimization to the UnitarySynthesis and HighLevelSynthesis synthesis passes when there are no gates to synthesize. Previously these passes would iterate over the entire DAG and check every gate to determine that None needed to be synthesized. While this is relatively quick for very large circuits this can take 100s of ms. However, this was wasted work because the DAG carries a dictionary of op names in the circuit so we can determine in constant time whether any of the operations to synthesize are present up front and skip the bulk of the iteration. To improve the impact here the DAGCircuit.count_ops() method is updated to skip the recursion if no control flow operations are present. Otherwise we'd still be iterating over the DAG (in a faster manner) which would limit the improvement from this commit. This isn't the best approach for that as it uses a hardcoded list of control flow operations which doesn't seem super general purpose, but as this hard coded set of instructions is already used elsewhere in the DAGCircuit this isn't making the situation any worse. If/when we expand recursive objects this can be revisited (and we'll likely not be able to avoid the iteration in count ops). With these changes the time these passes take when there are no operations to synthesize only takes ~10-20 microseconds.

A similar optimization should be considered for UnrollCustomDefinitions as this takes an even longer amount of time to iterate when there is nothing to translate. However, it wasn't done as part of this PR as to check the equivalence library has an entry we need to work with gate objects (well actually name and number of qubits as that's all that's used from the object for a lookup) and the name from the op count dictionary is not sufficient for a lookup. So this will need to be handled independently in a separate PR.

Details and comments

This commit makes a small optimization to the UnitarySynthesis and
HighLevelSynthesis synthesis passes when there are no gates to
synthesize. Previously these passes would iterate over the entire DAG
and check every gate to determine that None needed to be synthesized.
While this is relatively quick for very large circuits this can take
100s of ms. However, this was wasted work because the DAG carries a
dictionary of op names in the circuit so we can determine in constant
time whether any of the operations to synthesize are present up front
and skip the bulk of the iteration. To improve the impact here the
DAGCircuit.count_ops() method is updated to skip the recursion if no
control flow operations are present. Otherwise we'd still be iterating
over the DAG (in a faster manner) which would limit the improvement
from this commit. This isn't the best approach for that as it uses a
hardcoded list of control flow operations which doesn't seem super
general purpose, but as this hard coded set of instructions is
already used elsewhere in the DAGCircuit this isn't making the
situation any worse. If/when we expand recursive objects this can be
revisited (and we'll likely not be able to avoid the iteration in
count ops). With these changes the time these passes take when there are
no operations to synthesize only takes ~5-15 microseconds.

A similar optimization should be considered for UnrollCustomDefinitions
as this takes an even longer amount of time to iterate when there is
nothing to translate. However, it wasn't done as part of this PR as to
check the equivalence library has an entry we need to work with gate
objects (well actually name and number of qubits as that's all that's
used from the object for a lookup) and the name from the op count
dictionary is not sufficient for a lookup. So this will need to be
handled independently in a separate PR.
@mtreinish mtreinish added performance Changelog: None Do not include in changelog mod: transpiler Issues and PRs related to Transpiler labels Sep 6, 2023
@mtreinish mtreinish added this to the 0.45.0 milestone Sep 6, 2023
@qiskit-bot
Copy link
Collaborator

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

  • @Qiskit/terra-core

Copy link
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 seems like a generally good idea to me. The control-flow ops being somewhat hardcoded is a little sub-optimal, but then so's everything about our handling of control-flow operations within the DAG IR, so I'm not desperately worried about it. We can revisit if/when we improve our representation of them.

qiskit/dagcircuit/dagcircuit.py Outdated Show resolved Hide resolved
qiskit/transpiler/passes/synthesis/unitary_synthesis.py Outdated Show resolved Hide resolved
Copy link
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 looks good to me, and having the data attribute in a formal, public place makes it feel a bit less shaky and less like we'll forget to update it.

@jakelishman jakelishman added this pull request to the merge queue Sep 7, 2023
Merged via the queue into Qiskit:main with commit a02e0a3 Sep 7, 2023
14 checks passed
@mtreinish mtreinish deleted the skip-unitary-synthesis branch September 14, 2023 19:30
@mtreinish mtreinish mentioned this pull request Sep 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: None Do not include in changelog mod: transpiler Issues and PRs related to Transpiler performance
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants