-
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
Improve efficiency of RemoveFinalMeasurement transpiler pass #7039
Conversation
The RemoveFinalMeasurement was determining which operations were at the end of a circuit quite inefficiently. It was searching over the entire DAG to find barrier and measurement instructions and then checking any that were found if they're children were output nodes. While instead it'd be much more efficient to chack the parent of each output node for whether it's a barrier or a measurement. Additionally, the output dag was being needless rebuilt by modifying the input and then looping over all nodes in the dag again and copy the node to a new dag. While instead we can just return the modified input graph. This commit makes those changes to improve the efficiency of the pass. Fixes Qiskit#7038
Running this script: import time
from qiskit.circuit.random import random_circuit
from qiskit.converters import circuit_to_dag
widths = [10, 100, 1000]
for width in widths:
circuit = random_circuit(width, width, measure=True, seed=42)
start = time.time()
circuit.remove_final_measurements()
stop = time.time()
print(f"Width {width}: {stop - start}") Running with this PR:
Running from main without this PR:
|
bd96bab
to
89b1acf
Compare
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.
Looks good! QuantumCircuit.remove_final_measurements
would probably also benefit from a similar treatment, but that can be for another issue.
except StopIteration as e: | ||
raise DAGCircuitError( | ||
"Invalid dagcircuit input node %s has no output" % self.input_map[wire] | ||
) from e |
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.
Out of curiosity, we don't usually guard against a malformed DAGCircuit, was there a reason to here?
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.
Pylint was yelling at me locally about raising stopiteration without it. This made it happy...
This actually will apply to the circuit method too, internally it just uses the transpiler pass: https://github.com/Qiskit/qiskit-terra/blob/main/qiskit/circuit/quantumcircuit.py#L2140-L2181(it's really the only thing using the pass) |
Summary
The RemoveFinalMeasurement was determining which operations were at the
end of a circuit quite inefficiently. It was searching over the entire
DAG to find barrier and measurement instructions and then checking any
that were found if they're children were output nodes. While instead
it'd be much more efficient to chack the parent of each output node for
whether it's a barrier or a measurement. Additionally, the output dag
was being needless rebuilt by modifying the input and then looping over
all nodes in the dag again and copy the node to a new dag. While instead
we can just return the modified input graph. This commit makes those
changes to improve the efficiency of the pass.
Details and comments
Fixes #7038