-
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
Fix performance regression in UnitarySynthesis #13375
Fix performance regression in UnitarySynthesis #13375
Conversation
This commit fixes a performance regression that was introduced in PR Qiskit#13141. When the pass is looking up the preferred synthesis direction for a unitary based on the connectvity constraints the connectivity was being provided as a PyList. To look up the edge in connectivity set this meant we needed to iterate over the list and then create a set that rust could lookup if it contains an edge or it's reverse. This has significant overhead because its iterating via python and also iterating per decomposition. This commit addresses this by changing the input type to be a HashSet from Python so Pyo3 will convert a pyset directly to a HashSet once at call time and that's used by reference for lookups directly instead of needing to iterate over the list each time.
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 11575706080Details
💛 - Coveralls |
If we're using the default plugin the execution will happen in rust and we don't need to build the plugin data views that are defined in the plugin interface. Profiling the benchpress test using the hamlib hamiltonian: ham_graph-2D-grid-nonpbc-qubitnodes_Lx-5_Ly-186_h-0.5-all-to-all that caught this originally regression was showing an inordinate amount of time being spent in the construction of `_build_gate_lengths_by_qubit` and `_build_gate_errors_by_qubit` which isn't being used because this happens internally in rust now. To mitigate this overhead this commit migrates the sections computing these values to the code branch that uses them and not the default plugin branch that uses rust.
@@ -268,7 +268,7 @@ fn py_run_main_loop( | |||
new_ids, | |||
min_qubits, | |||
target, | |||
coupling_edges, | |||
coupling_edges.clone(), |
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.
We can avoid this clone if we refactor the functions a bit to split the python interface out and use a reference for the recursion. Not sure how important this is because this only comes up during control flow processing and we're already slower there because of the python usage and circuit to dag conversion. Maybe something to fix for when we make a dag native control flow op.
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 it would make sense to revisit this when we get to have rust-native control flow op.
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.
LGTM. Thanks for the catch :)
Summary
This commit fixes a performance regression that was introduced in PR #13141. When the pass is looking up the preferred synthesis direction for a unitary based on the connectvity constraints the connectivity was being provided as a PyList. To look up the edge in connectivity set this meant we needed to iterate over the list and then create a set that rust could lookup if it contains an edge or it's reverse. This has significant overhead because its iterating via python and also iterating per decomposition. This commit addresses this by changing the input type to be a HashSet from Python so Pyo3 will convert a pyset directly to a HashSet once at call time and that's used by reference for lookups directly instead of needing to iterate over the list each time.
Details and comments