-
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
Reuse VF2 scoring views for all scoring #11115
Conversation
One or more of the the following people are requested to review this:
|
Pull Request Test Coverage Report for Build 6646439673
💛 - Coveralls |
I reran the benchmarking script from: #11112 (comment) with this PR applied and graphed the output here. There is a significant performance improvement with this: |
As part of the VF2Layout and VF2PostLayout passes when there are a large number of matches found we're spending an inordinate amount of time in scoring rebuilding the same views over and over again of the interaction graph for each scoring call. For example, in one test cProfile showed that with Qiskit#11112 when running transpile() on a 65 Bernstein Vazirani circuit with a secret of all 1s for FakeSherbrooke with optimization_level=3 we were calling vf2_utils.score_layout() 161,761 times which took a culmulative time of 14.33 secs. Of that time though we spent 5.865 secs building the edge list view. These views are fixed for a given interaction graph which doesn't change during the duration of the run() method on these passes. To remove this inefficiency this commit moves the construction of the views to the beginning of the passes and just reuses them by reference for each scoring call, avoiding the reconstruction overhead.
This commit adds a new pyclass written in rust that wraps a rust Vec. Previously the scoring function also used an dict->IndexMap conversion, but the mapping structure wasn't necessary and added additional overhead, so it was converted to a list/Vec to speed up the execution even further. By using this new pyclass as the input to the rust scoring function we avoid converting the edge list from a list to an Vec on each call which will reduce the overhead even further.
6c9b34e
to
3264e06
Compare
Now that #11112 has merged I've rebased this so it should be ready for review |
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, great idea!
The implementation makes me wonder if in the future we should have some sort of VF2Scorer
class that builds these and holds them as instance data among any other data that is reused between scorings. The reason being to encapsulate the internals of scoring without forcing client code to be aware of them (i.e. rather than threading a bunch of parameters around, we might call a VF2Scorer::score
method and pass just the layout).
I think that's a good idea. In the interest of minimizing the interface changes between 0.45.0rc1 and 0.45.0 I think we should just go with this for now (for backport). But I'll open an issue to track refactoring the scoring to be a pyclass that tracks everything like you're proposing. |
* Reuse VF2 scoring views for all scoring As part of the VF2Layout and VF2PostLayout passes when there are a large number of matches found we're spending an inordinate amount of time in scoring rebuilding the same views over and over again of the interaction graph for each scoring call. For example, in one test cProfile showed that with #11112 when running transpile() on a 65 Bernstein Vazirani circuit with a secret of all 1s for FakeSherbrooke with optimization_level=3 we were calling vf2_utils.score_layout() 161,761 times which took a culmulative time of 14.33 secs. Of that time though we spent 5.865 secs building the edge list view. These views are fixed for a given interaction graph which doesn't change during the duration of the run() method on these passes. To remove this inefficiency this commit moves the construction of the views to the beginning of the passes and just reuses them by reference for each scoring call, avoiding the reconstruction overhead. * Add EdgeList Rust pyclass to avoid repeated conversion This commit adds a new pyclass written in rust that wraps a rust Vec. Previously the scoring function also used an dict->IndexMap conversion, but the mapping structure wasn't necessary and added additional overhead, so it was converted to a list/Vec to speed up the execution even further. By using this new pyclass as the input to the rust scoring function we avoid converting the edge list from a list to an Vec on each call which will reduce the overhead even further. (cherry picked from commit a67fe87)
* Reuse VF2 scoring views for all scoring As part of the VF2Layout and VF2PostLayout passes when there are a large number of matches found we're spending an inordinate amount of time in scoring rebuilding the same views over and over again of the interaction graph for each scoring call. For example, in one test cProfile showed that with #11112 when running transpile() on a 65 Bernstein Vazirani circuit with a secret of all 1s for FakeSherbrooke with optimization_level=3 we were calling vf2_utils.score_layout() 161,761 times which took a culmulative time of 14.33 secs. Of that time though we spent 5.865 secs building the edge list view. These views are fixed for a given interaction graph which doesn't change during the duration of the run() method on these passes. To remove this inefficiency this commit moves the construction of the views to the beginning of the passes and just reuses them by reference for each scoring call, avoiding the reconstruction overhead. * Add EdgeList Rust pyclass to avoid repeated conversion This commit adds a new pyclass written in rust that wraps a rust Vec. Previously the scoring function also used an dict->IndexMap conversion, but the mapping structure wasn't necessary and added additional overhead, so it was converted to a list/Vec to speed up the execution even further. By using this new pyclass as the input to the rust scoring function we avoid converting the edge list from a list to an Vec on each call which will reduce the overhead even further. (cherry picked from commit a67fe87) Co-authored-by: Matthew Treinish <[email protected]>
Summary
As part of the VF2Layout and VF2PostLayout passes when there are a large
number of matches found we're spending an inordinate amount of time in
scoring rebuilding the same views over and over again of the interaction
graph for each scoring call. For example, in one test cProfile showed
that with #11112 when running
transpile()
on a 65 qubit Bernstein Vaziranicircuit with a secret of all 1s for
FakeSherbrooke
withoptimization_level=3 we were calling
vf2_utils.score_layout()
161,761times which took a cumulative time of 14.33 secs. Of that time though
we spent 5.865 secs building the edge list view.
These views are fixed for a given interaction graph which doesn't change
during the duration of the run() method on these passes. To remove this
inefficiency this commit moves the construction of the views to the
beginning of the passes and just reuses them by reference for each
scoring call, avoiding the reconstruction overhead.
Details and comments
This PR is based on top of #11112 and will need to rebased after #11112 merges. To see just what changes in this PR you can look at:8cdc4ebThis has been rebased.