-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
DAGCircuit layers uses a shallow copy #378
Conversation
I would also like to not that my total runtime for the same problem goes down to 4 minutes if I use the new |
@eddieschoute, can you check if the latest PR merged #523 by @ajavadia requires some changes to this PR, and update about the WIP status? It seems it has fallen off the radar a bit and might be a bit not fully compatible with the latest changes, but it would be great to be able to solve the issue and provide a performance bump thanks to your contribution. |
@diego-plan9 I can look at it again, but there is another bug that will make tests fail (#382) that needs to be addressed too. |
Thanks @eddieschoute ! Perhaps deviating a bit to tackle the bug in another PR and then coming back to this one would be more convenient? |
Of course. But I figured you wouldn't want to merge changes into the master branch that have failing tests. (I am not planning on addressing the issue myself.) |
I have resolved the conflicts, but a close look is needed if it supports the same functionality that has been added to the layers function. I saw that now
None of the tests (besides that bug) seem to have broken, except for |
Great, thanks!
Indeed 👍
No worries, it was unclear to me if you were meant to handle the bugfix yourself - I'm labeling his PR as Can you confirm me that this PR would then be ready for review and out of |
Yes it is ready. I have removed the WIP status. |
@eddieschoute, would you mind to open an issue before creating the PR the next time, please? This way we ease the tracking. |
* The layers function used to return a normally constructed DAGCircuit object for each layer. * Now instead it constructs a shallow copy that provides a limited "view" onto the operations being performed in a layer. * Added multigraph_layers method to yield the nodes in the multigraph layer-by-layer. This functionality is being duplicated inside DAGCircuit and can be refactored out.
* Added a return statement if a layer was going to be empty, e.g. when containing only output nodes. * Cleanup of code.
* The next_layer was being set to empty before being stored for the next iteration.
* Multigraph_layers was not taking multiplicity of edges into account and thus not emitting certain edges at the right times. * Added test case for layers
@eddieschoute I rebased this branch and fixed the test according to the explanation I gave in #382 (comment). It looks good. Thanks for the contribution. |
* DAGCircuit layers returns shallow copies * The layers function used to return a normally constructed DAGCircuit object for each layer. * Now instead it constructs a shallow copy that provides a limited "view" onto the operations being performed in a layer. * Added multigraph_layers method to yield the nodes in the multigraph layer-by-layer. This functionality is being duplicated inside DAGCircuit and can be refactored out. * Layers would not properly emit a StopIteration * Added a return statement if a layer was going to be empty, e.g. when containing only output nodes. * Cleanup of code. * Fixed bug in multigraph_layers * The next_layer was being set to empty before being stored for the next iteration. * Take multiedges into account * Multigraph_layers was not taking multiplicity of edges into account and thus not emitting certain edges at the right times. * Added test case for layers * Fix naming of yielded dict. And call-sites of layers * Fix type of partition field in layers * Adhering to style guidelines * Changed maps/filters to comprehensions * fix test according to explanation in #382
* DAGCircuit layers returns shallow copies * The layers function used to return a normally constructed DAGCircuit object for each layer. * Now instead it constructs a shallow copy that provides a limited "view" onto the operations being performed in a layer. * Added multigraph_layers method to yield the nodes in the multigraph layer-by-layer. This functionality is being duplicated inside DAGCircuit and can be refactored out. * Layers would not properly emit a StopIteration * Added a return statement if a layer was going to be empty, e.g. when containing only output nodes. * Cleanup of code. * Fixed bug in multigraph_layers * The next_layer was being set to empty before being stored for the next iteration. * Take multiedges into account * Multigraph_layers was not taking multiplicity of edges into account and thus not emitting certain edges at the right times. * Added test case for layers * Fix naming of yielded dict. And call-sites of layers * Fix type of partition field in layers * Adhering to style guidelines * Changed maps/filters to comprehensions * fix test according to explanation in Qiskit#382
Fix #749
In my profiling the
DAGCircuit.layers()
function came forward as the main culprit to my runtime, at about 90% of the total run time. 60% of the total time is spent in a the function_add_wire
which is of course a bit silly considering the trivial thing it does. Turns out that DAGCircuit constructs a full copy of itself besides the gates, which turns out to be very slow. Instead of making a full copy it now returns a shallow copy.Description
The layers function now constructs a shallow copy of DAGCircuit and modifies it such that it only contains the nodes of the current layer. That being: All input and output nodes disregarding whether they are used or not, and exactly one layer of op_nodes.
Profiling results
On a relatively small circuit containing a 1000 gates my runtime goes from 22 minutes on the
dag-generators
branch (#371 ) to 16 minutes by using this change. The total runtime oflayers
goes from 18 minutes to 9 minutes. Still not quite satisfactory but closer.Motivation and Context
I use the layers functionality extremely often to iterate through the layers and compare the cost of running a circuit between slight variations of the circuit.
How Has This Been Tested?
I added a test case for the layers functionality. (I was surprised to see that nothing was being tested before.) The test case is the only one that fails. There is some strange behavior in how the multi_graph in the DAGCircuit is constructed.
I'm inspecting the DAG multigraph when making a test and it just doesnt make sense. I have nodes that have edges to nodes that should be unrelated. E.g
from test_dagcircuit.py will have some strange edges. It has an edge from clbit0 to the
x
operation being performed on qubit1 with clbit1. It seems related to how_def_bits_in_condition
adds all classical bits of a register to the operation dependencies.Types of changes
Breaking: layers now is a generator. Supersedes #371
Checklist: