Skip to content
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] Use VF2 to find a partial layout for seeding a SabreLayout trial #10169

Closed
wants to merge 9 commits into from

Conversation

mtreinish
Copy link
Member

Summary

This commit builds on the VF2PartialLayout pass which was an experiment available as an external plugin here:

https://github.com/mtreinish/vf2_partial_layout

That pass used the vf2 algorithm in rustworkx to find the deepest partial interaction graph of a circuit which is isomorphic with the coupling graph and uses that mapping to apply an initial layout. The issue with the performance of that pass was the selection of the qubits outside the partial interaction graph. Selecting the mapping for those qubits is similar to the same heuristic layout that SabreLayout is trying to solve, just for a subset of qubits. In VF2PartialLayout a simple nearest neighbor based approach was used for selecting qubits from the coupling graph for any virtual qubits outside the partial layout. In practice this ended up performing worse than SabreLayout.

To address the shortcomings of that pass this commit combines the partial layout selection from that external plugin with SabreLayout. The sabre layout algorithm starts by randomly selecting a layout and then progressively working forwards and backwards across the circuit and swap mapping it to find the permutation caused by inserted swaps. Those permutations are then used to modify the random layout and eventual an initial layout that minimizes the number of swaps needed is selected. With this commit instead of using a completely random layout for all the initial guesses this starts a single trial with the partial layout found in the same way as VF2PartialLayout. Then the remaining qubits are selected at random and the Sabrelayout algorithm is run in the same manner as before. This hopefully should improve the quality of the results because we're starting from a partial layout that doesn't require swaps for those qubits.

A similar (almost identical approach) was tried in #9174 except instead of seeding a single trial with the partial layout it used the partial layout for all the the trials. In that case the results were not generally better and the results were mixed. At the time my guess was that using the partial layout constrained the search space too much and was inducing more swaps to be needed. However, looking at the details in issue #10160 this adapts #9174 to see if doing the partial layout in a more limited manner has any impact there.

Details and comments

  • Benchmark the pass to test quality and runtime
    • Investigate different splits in trials between fully random and partial layout
  • Fix tests to adapt to layout changes caused by this
  • Add release notes

@mtreinish mtreinish added the on hold Can not fix yet label May 26, 2023
This commit builds on the VF2PartialLayout pass which was an experiment
available as an external plugin here:

https://github.com/mtreinish/vf2_partial_layout

That pass used the vf2 algorithm in rustworkx to find the deepest
partial interaction graph of a circuit which is isomorphic with the
coupling graph and uses that mapping to apply an initial layout. The
issue with the performance of that pass was the selection of the qubits
outside the partial interaction graph. Selecting the mapping for those
qubits is similar to the same heuristic layout that SabreLayout is
trying to solve, just for a subset of qubits. In VF2PartialLayout a
simple nearest neighbor based approach was used for selecting qubits
from the coupling graph for any virtual qubits outside the partial
layout. In practice this ended up performing worse than SabreLayout.

To address the shortcomings of that pass this commit combines the
partial layout selection from that external plugin with SabreLayout.
The sabre layout algorithm starts by randomly selecting a layout and
then progressively working forwards and backwards across the circuit
and swap mapping it to find the permutation caused by inserted swaps.
Those permutations are then used to modify the random layout and
eventual an initial layout that minimizes the number of swaps needed is
selected. With this commit instead of using a completely random layout
for all the initial guesses this starts a single trial with the partial
layout found in the same way as VF2PartialLayout. Then the remaining
qubits are selected at random and the Sabrelayout algorithm is run in
the same manner as before. This hopefully should improve the quality
of the results because we're starting from a partial layout that
doesn't require swaps for those qubits.

A similar (almost identical approach) was tried in Qiskit#9174 except instead
of seeding a single trial with the partial layout it used the partial
layout for all the the trials. In that case the results were not
generally better and the results were mixed. At the time my guess was
that using the partial layout constrained the search space too much and
was inducing more swaps to be needed. However, looking at the details in
issue Qiskit#10160 this adapts Qiskit#9174 to see if doing the partial layout in a
more limited manner has any impact there.
This commit drops the vf2 layout scoring from the sabre layout partial
layout code. This code was just taken from the standalone vf2 passes
(VF2Layout and VF2PostLayout) which tries multiple isomorphic subgraphs
and figures out which layout has the best error characteristics.
However, in the case of using a partial layout for sabre this is just
wasted CPU cycles because we're not finalizing the layout and when we
run sabre the actual layout used will be different. So we just need to
pick any isomorphic subgraph and use that as a partial starting point.
This commit removes all the multiple subgraph and scoring logic to
improve the runtime performance with this branch.
This commit tweaks the algorithm for the initial layout guess when using
a partial layout to use the nearest neighbor qubits instead of just a
random order. This should lead to better results because there is less
back and forth needed to bring the qubits together.
@coveralls
Copy link

Pull Request Test Coverage Report for Build 5719974347

  • 147 of 150 (98.0%) changed or added relevant lines in 2 files are covered.
  • 6 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.03%) to 85.917%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/transpiler/passes/layout/sabre_layout.py 84 87 96.55%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/lex.rs 6 90.63%
Totals Coverage Status
Change from base Build 5684162640: 0.03%
Covered Lines: 73207
Relevant Lines: 85207

💛 - Coveralls

This commit increases the heuristic effort for sabre layout and routing.
This is made through 2 changes, the first is the depth of the internal
lookahead heuristic used in sabre swap has been increased from 20 to 72.
This is just a stop-gap for a potential reworking of the lookahead
heuristic. In local testing for larger backends and deeper circuits in
this is showing better output results than the current default of 20
without any runtime impact. The other aspect is that the trial counts
for each optimization level > 0 is increased 5x. This has a runtime cost,
but it the performance of the rust sabre implementation is fast enough
that even running the algorithm with more trials it is not a bottleneck
for typical compilation.

Related to Qiskit#10160
@mtreinish
Copy link
Member Author

This has been superseded by #10829 and #10721

@mtreinish mtreinish closed this Sep 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
on hold Can not fix yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants