-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Fully port Optimize1qGatesDecomposition to Rust #12959
Conversation
One or more of the following people are relevant to this code:
|
I ran some asv benchmarks on this and it's yielding very good looking performance improvements:
|
Pull Request Test Coverage Report for Build 10634728662Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
6ebfff0
to
5c9d285
Compare
5c9d285
to
621e60c
Compare
8569121
to
7eaa954
Compare
7eaa954
to
18eeab7
Compare
This commit builds off of Qiskit#12959 and the other data model in Rust infrastructure and migrates the InverseCancellation pass to operate fully in Rust. The full path of the transpiler pass now never leaves Rust until it has finished modifying the DAGCircuit. There is still some python interaction necessary to handle parts of the data model that are still in Python, mainly for handling parameter expressions. But otherwise the entirety of the pass operates in rust now. This is just a first pass at the migration here, it moves the pass to use loops in rust. The next steps here are to look at operating the pass in parallel. There is no data dependency between the optimizations being done for different inverse gates/pairs so we should be able to the throughput of the pass by leveraging multithreading to handle each inverse option in parallel. This commit does not attempt this though, because of the Python dependency and also the data structures around gates and the dag aren't really setup for multithreading yet and there likely will need to be some work to support that. Fixes Qiskit#12271 Part of Qiskit#12208
18eeab7
to
0c8b668
Compare
This commit builds off of Qiskit#12959 and the other data model in Rust infrastructure and migrates the InverseCancellation pass to operate fully in Rust. The full path of the transpiler pass now never leaves Rust until it has finished modifying the DAGCircuit. There is still some python interaction necessary to handle parts of the data model that are still in Python, mainly for handling parameter expressions. But otherwise the entirety of the pass operates in rust now. This is just a first pass at the migration here, it moves the pass to use loops in rust. The next steps here are to look at operating the pass in parallel. There is no data dependency between the optimizations being done for different inverse gates/pairs so we should be able to the throughput of the pass by leveraging multithreading to handle each inverse option in parallel. This commit does not attempt this though, because of the Python dependency and also the data structures around gates and the dag aren't really setup for multithreading yet and there likely will need to be some work to support that. Fixes Qiskit#12271 Part of Qiskit#12208
This commit builds off of Qiskit#12550 and the other data model in Rust infrastructure and migrates the Optimize1qGatesDecomposition pass to operate fully in Rust. The full path of the transpiler pass now never leaves rust until it has finished modifying the DAGCircuit. There is still some python interaction necessary to handle parts of the data model that are still in Python, mainly calibrations and parameter expressions (for global phase). But otherwise the entirety of the pass operates in rust now. This is just a first pass at the migration here, it moves the pass to be a single for loop in rust. The next steps here are to look at operating the pass in parallel. There is no data dependency between the optimizations being done by the pass so we should be able to the throughput of the pass by leveraging multithreading to handle each run in parallel. This commit does not attempt this though, because of the Python dependency and also the data structures around gates and the dag aren't really setup for multithreading yet and there likely will need to be some work to support that (this pass is a good candidate to work through the bugs on that). Part of Qiskit#12208
0c8b668
to
317a057
Compare
Now that #12550 has merged I've rebased this and it's ready for review. |
This commit builds off of Qiskit#12959 and the other data model in Rust infrastructure and migrates the InverseCancellation pass to operate fully in Rust. The full path of the transpiler pass now never leaves Rust until it has finished modifying the DAGCircuit. There is still some python interaction necessary to handle parts of the data model that are still in Python, mainly for handling parameter expressions. But otherwise the entirety of the pass operates in rust now. This is just a first pass at the migration here, it moves the pass to use loops in rust. The next steps here are to look at operating the pass in parallel. There is no data dependency between the optimizations being done for different inverse gates/pairs so we should be able to the throughput of the pass by leveraging multithreading to handle each inverse option in parallel. This commit does not attempt this though, because of the Python dependency and also the data structures around gates and the dag aren't really setup for multithreading yet and there likely will need to be some work to support that. Fixes Qiskit#12271 Part of Qiskit#12208
Since we only are storing 12 enum fields (which are a single byte) using any heap allocated collection is completely overkill and will have more overhead that storing a statically sized array for all 12 variants. This commit adds a new struct that wraps a `[bool; 12]` to track which basis are supported and an API for tracking this. This simplifies the tracking of which qubit supports which EulerBasis, it also means other internal users of the 1q decomposition have a simplified API for working with the euler basis.
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 that euler_one_qubit_decomposer.rs
should be moved to crates/accelerate/src/synthesis/one_qubit
to match with the structure of the current synthesis library.
Similarly, it would be good if two_qubit_decompose.rs
would be moved to crates/accelerate/src/synthesis/two_qubits
We can reorganize these modules in a follow up PR. When I created these modules there wasn't any other synthesis in rust so there wasn't anywhere else to put them. I think it'll probably be best to do this at the same time we create a transpiler crate so the |
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.
Thanks a lot @mtreinish!! Apart from the cool optimizations, the PR also includes a lot of handy dag circuit utilities, and I think we would all benefit from having it merged soon (I definitely will). I left a few questions (just for my info) and a tiny non-blocking reno suggestion, but LGMT.
releasenotes/notes/optimize-1q-gates-decomposition-ce111961b6782ee0.yaml
Outdated
Show resolved
Hide resolved
…82ee0.yaml Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
This commit builds off of Qiskit#12959 and the other data model in Rust infrastructure and migrates the InverseCancellation pass to operate fully in Rust. The full path of the transpiler pass now never leaves Rust until it has finished modifying the DAGCircuit. There is still some python interaction necessary to handle parts of the data model that are still in Python, mainly for handling parameter expressions. But otherwise the entirety of the pass operates in rust now. This is just a first pass at the migration here, it moves the pass to use loops in rust. The next steps here are to look at operating the pass in parallel. There is no data dependency between the optimizations being done for different inverse gates/pairs so we should be able to the throughput of the pass by leveraging multithreading to handle each inverse option in parallel. This commit does not attempt this though, because of the Python dependency and also the data structures around gates and the dag aren't really setup for multithreading yet and there likely will need to be some work to support that. Fixes Qiskit#12271 Part of Qiskit#12208
This commit migrates the entirety of the CheckMap analysis pass to Rust. The pass operates solely in the rust domain and returns an `Option<(String, [u32; 2])>` to Python which is used to set the two property set fields appropriately. All the analysis of the dag is done in Rust. There is still Python interaction required though because control flow operations are only defined in Python. However the interaction is minimal and only to get the circuits for control flow blocks and converting them into DAGs (at least until Qiskit#13001 is complete). This commit is based on top of Qiskit#12959 and will need to be rebased after that merges. Closes Qiskit#12251 Part of Qiskit#12208
* Fully port CheckMap to Rust This commit migrates the entirety of the CheckMap analysis pass to Rust. The pass operates solely in the rust domain and returns an `Option<(String, [u32; 2])>` to Python which is used to set the two property set fields appropriately. All the analysis of the dag is done in Rust. There is still Python interaction required though because control flow operations are only defined in Python. However the interaction is minimal and only to get the circuits for control flow blocks and converting them into DAGs (at least until #13001 is complete). This commit is based on top of #12959 and will need to be rebased after that merges. Closes #12251 Part of #12208 * Use a Vec<Qubit> for wire_map instead of a HashMap This commit switches to using a Vec<Qubit> for the internal wire_map used to map control flow qubits. A HashMap was originally used because in Python a dictionary is used. However, in the rust domain the inner qubits are contiguous integers starting from 0 so a Vec can be used for better performance in the case we have control flow. * Update crates/accelerate/src/check_map.rs Co-authored-by: Raynel Sanchez <87539502+raynelfss@users.noreply.github.com> --------- Co-authored-by: Raynel Sanchez <87539502+raynelfss@users.noreply.github.com>
* Fully port InverseCancellation to Rust This commit builds off of #12959 and the other data model in Rust infrastructure and migrates the InverseCancellation pass to operate fully in Rust. The full path of the transpiler pass now never leaves Rust until it has finished modifying the DAGCircuit. There is still some python interaction necessary to handle parts of the data model that are still in Python, mainly for handling parameter expressions. But otherwise the entirety of the pass operates in rust now. This is just a first pass at the migration here, it moves the pass to use loops in rust. The next steps here are to look at operating the pass in parallel. There is no data dependency between the optimizations being done for different inverse gates/pairs so we should be able to the throughput of the pass by leveraging multithreading to handle each inverse option in parallel. This commit does not attempt this though, because of the Python dependency and also the data structures around gates and the dag aren't really setup for multithreading yet and there likely will need to be some work to support that. Fixes #12271 Part of #12208 * Remove temporary variable for chunk empty check * Destructure gate pairs * Rework short circuit logic
Since 8e5fab6 (Qiskitgh-12959), this branch has been dead, and the Rust method alluded to in it (`compute_error_one_qubit_sequence`) was removed. This is occasionally - but for some reason not always - detected by `pylint`, and it's a true error so should be removed. In fact, almost all of the Python code in `Optimize1qDecomposition` is dead from the perspective of that transpiler pass. However, `Optimize1qCommutation` has no concept of safe API boundaries, and is in fact still using all of these methods (and the default `UnitarySynthesis` plugin does a little too). A follow-up commit can reorganise the code to fix this, but this commit is intended to be mergeable faster, to unblock a couple of PRs that are triggering the pylint failure.
…13188) Since 8e5fab6 (gh-12959), this branch has been dead, and the Rust method alluded to in it (`compute_error_one_qubit_sequence`) was removed. This is occasionally - but for some reason not always - detected by `pylint`, and it's a true error so should be removed. In fact, almost all of the Python code in `Optimize1qDecomposition` is dead from the perspective of that transpiler pass. However, `Optimize1qCommutation` has no concept of safe API boundaries, and is in fact still using all of these methods (and the default `UnitarySynthesis` plugin does a little too). A follow-up commit can reorganise the code to fix this, but this commit is intended to be mergeable faster, to unblock a couple of PRs that are triggering the pylint failure.
Summary
This commit builds off of #12550 and the other data model in Rust
infrastructure and migrates the Optimize1qGatesDecomposition pass to
operate fully in Rust. The full path of the transpiler pass now never
leaves rust until it has finished modifying the DAGCircuit. There is
still some python interaction necessary to handle parts of the data
model that are still in Python, mainly calibrations and parameter
expressions (for global phase). But otherwise the entirety of the pass
operates in rust now.
This is just a first pass at the migration here, it moves the pass to be
a single for loop in rust. The next steps here are to look at operating
the pass in parallel. There is no data dependency between the
optimizations being done by the pass so we should be able to the
throughput of the pass by leveraging multithreading to handle each run
in parallel. This commit does not attempt this though, because of the
Python dependency and also the data structures around gates and the
dag aren't really setup for multithreading yet and there likely will
need to be some work to support that (this pass is a good candidate to
work through the bugs on that).
Details and comments
Part of #12208
This PR is based on top of #12550 and as such github shows the entire contents of #12550 in addition to the contents of this PR. To see the contents of this PR you can look at HEAD on this branch, or just look at:
0c8b668
TODO:
DAGCircuit
to Rust #12550 mergeseuler_one_qubit_decomposer
module