-
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
[WIP] Hacking sabre_swap to work on the DAGDependency graph #8951
[WIP] Hacking sabre_swap to work on the DAGDependency graph #8951
Conversation
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:
|
Here are some quick benchmarking results on some of the red-queen's
|
Pull Request Test Coverage Report for Build 3282210238
💛 - 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.
I think we should consider at a larger scale how we might want to add DAGDependency
to paths within PassManager
or above, without breaking the current BasePass
interface which defines that the input to run
is DAGCircuit
, and the input to __call__
is QuantumCircuit
. I'm also concerned with fitting this into other work, where we eventually want to be replacing the IR of the transpiler with some form of classical control-flow graph - I don't want us to start adding half-done features to certain transpiler passes without having a clear path in mind.
I don't think it's a good idea to overload run
like this; as here, it ends up requiring every pass owner to manually implement their own dispatchers, or have messy nested code. From a typing perspective, we can't really apply standard OO principles to the methods any more, because we can't have BasePass
take run(data: DAGCircuit | DAGDependency)
without violating the typing of all existing passes (this is essentially the same problem as the first paragraph).
Ignoring the potential CFG change to the IR, off the top of my head, I would consider adding more than one "run" method that passes can define - one for DAGCircuit
(probably needs to still be called run
for backwards compatibility) and one for DAGDependency
. PassManager
can then call what's best at the given time, and do any conversions that might be necessary.
Just to expand a bit more on the code: the Rust-level changes of decoupling "edges" from qubits/clbits looks fine to me (and I'm excited to see the immediate improvements in size/depth!), and the way it's been done at the technical level generally looks ok. It has some implications for some work of mine (unpublished) that massively speeds up SabreSwap for large circuits, but I can easily reconcile that. On the Python side: I think far more of the Python parts of the |
@jakelishman, thanks for the very thorough feedback. Below are a few (subjective) thoughts on the subject. I completely agree that from the perspective of a compiler, having multiple internal representations (IRs) of a circuit, allowing the transpiler flow to switch between different representations, and having different transpiler passes for different internal representations seems like a great approach. However, despite me trying to use On the positive side, On the negative side, constructing a
This very simple circuit has G = 2N-1 gates. However, as all X-gates commute with each other, and all Y-gates commute with each other, while none of the X-gates commute with any of Y-gates, the resulting There are a few more caveats about I believe If we decide not to create an IR out of What do you think? |
@jakelishman, do you agree that we do not want to make |
I don't think we've got any solid decisions on how the |
Thanks @jakelishman. I am happy to close this PR or to put it on hold until your PR #9012 is merged, whichever you think it's best. |
I am closing this PR. The |
Summary
Following up on the discussion from
qiskit-dev-synthesis
meeting, I have hacked the code insabre_swap.py
andsabre_dag.rs
to work on bothDAGCircuit
andDAGDependency
, thus having the option to exploit commutativity between gates, as was also suggested in #6247 and in https://arxiv.org/pdf/2202.03459.pdf.The few required changes were as follows:
SabreDAG
insabre_dag.rs
now explicitly receives the list of edges (instead of reconstructing the edges based onqubits
andclbits
involved, basically assuming that the DAG is aDAGCircuit
).sabre_swap.py
, both forDAGCircuit
andDAGDependency
, and is based on examining nodes' direct predecessors and direct successors.SabreSwap.run()
accepts an additional argumentdo_commutative_analysis
(which isFalse
by default). WhenTrue
, it builds a helperDAGDependency
out of theDAGCircuit
passed to it.There is also a temporary file
sabre_experiments.py
which can runSabreSwap
with various options and checks the equivalence between the original and the transpiled circuits (following the ideas from #8597). This seems to work, except that:NodeIndex::new(...)
lines and randomly adding "&" symbols)sabre_swap.py
.Feedback would be appreciated.