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

Fix an edge case in Sabre's release valve #13114

Merged
merged 10 commits into from
Sep 11, 2024

Conversation

Cryoris
Copy link
Contributor

@Cryoris Cryoris commented Sep 9, 2024

Summary

Fixes #13081.

Details and comments

If a Sabre trial does not find a set of Swaps to route nodes, the "release valve" adds Swaps to route the two-qubit gate in between the the closest two qubits. In rare cases, this leads to more than one gate being routable, which was not handled correctly previously.

As I understand it this should only ever occur if the release-valve adds a single swap and we have a scenario like

A - B - A - B  --apply swap--> A - A - B - B

If more than one swap gate is applied it should not be possible that two gates are routable, so the code now only checks for a second routable gate if we insert a single swap. If someone can find a counterexample we can change the code to check for any routable gate after the release valve 🙂

Cryoris and others added 3 commits September 9, 2024 15:35
If a Sabre trial does not find a set of Swaps to route nodes, the "release valve" adds Swaps to route the two-qubit gate in between the the closest two qubits. In rare cases, this leads to _more_ than one gate being routable, which was not handled correctly previously.

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
@Cryoris Cryoris added stable backport potential The bug might be minimal and/or import enough to be port to stable Changelog: Bugfix Include in the "Fixed" section of the changelog labels Sep 9, 2024
@Cryoris Cryoris added this to the 1.2.1 milestone Sep 9, 2024
@Cryoris Cryoris requested a review from a team as a code owner September 9, 2024 14:36
@qiskit-bot
Copy link
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core
  • @kevinhartman
  • @mtreinish

crates/accelerate/src/sabre/route.rs Outdated Show resolved Hide resolved
@@ -573,14 +600,16 @@ pub fn swap_map_trial(
}
if routable_nodes.is_empty() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't comment above this line, but is there any reason we shouldn't use a SmallVec for routable_nodes itself?

And, should we increase the capacity of the pre-allocation to 3 now on line 573?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't necessarily, because the release valve should only be taken rarely, and we don't want to overallocate the happy path, and we should still only be routing two nodes in the new case.

crates/accelerate/src/sabre/route.rs Outdated Show resolved Hide resolved
Cryoris and others added 5 commits September 9, 2024 21:32
Co-authored-by: Kevin Hartman <kevin@hart.mn>
Co-authored-by: Kevin Hartman <kevin@hart.mn>
@coveralls
Copy link

coveralls commented Sep 10, 2024

Pull Request Test Coverage Report for Build 10795320615

Warning: 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

  • 13 of 26 (50.0%) changed or added relevant lines in 2 files are covered.
  • 14 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.02%) to 89.142%

Changes Missing Coverage Covered Lines Changed/Added Lines %
crates/accelerate/src/sabre/route.rs 9 22 40.91%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/lex.rs 2 92.98%
crates/qasm2/src/parse.rs 12 97.15%
Totals Coverage Status
Change from base Build 10794993036: -0.02%
Covered Lines: 73023
Relevant Lines: 81918

💛 - Coveralls

@Cryoris
Copy link
Contributor Author

Cryoris commented Sep 10, 2024

With #13119 merged, CI should pass now I think 🙂

Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, I have a small inline nit comment on code style but it's not significant or a blocker. I'm running the 1000q QV reproducer I put in the original issue to confirm it's fixed once I confirm it's fixed I'll add this to the merge queue.

Comment on lines +345 to +348
.filter_map(|&swap_qubit| self.front_layer.qubits()[swap_qubit.index()])
// remove the closest_node, which we know we already routed
.filter(|(node_index, _other_qubit)| *node_index != closest_node)
.map(|(_node_index, other_qubit)| other_qubit);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this just be a single filter map. Something like:

Suggested change
.filter_map(|&swap_qubit| self.front_layer.qubits()[swap_qubit.index()])
// remove the closest_node, which we know we already routed
.filter(|(node_index, _other_qubit)| *node_index != closest_node)
.map(|(_node_index, other_qubit)| other_qubit);
.filter_map(|&swap_qubit| {
self.front_layer.qubits()[swap_qubit.index()]).map(|(node_index, other_qubit)| {
// remove the closest_node, which we know we already routed
if node_index != closest_node {
Some(other_qubit)
} else {
None
}
})
});

Or even:

Suggested change
.filter_map(|&swap_qubit| self.front_layer.qubits()[swap_qubit.index()])
// remove the closest_node, which we know we already routed
.filter(|(node_index, _other_qubit)| *node_index != closest_node)
.map(|(_node_index, other_qubit)| other_qubit);
.filter_map(|&swap_qubit| self.front_layer.qubits()[swap_qubit.index()])
// remove the closest_node, which we know we already routed
.filter_map(|(node_index, other_qubit)| if *node_index != closest_node {
Some(other_qubit)
} else {
None
})

Not that this makes a big difference. I'm surprised clippy isn't complaining about the filter followed by a map though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you're really going hard on fancy methods, you can even do (*node_index != closest_node).then_some(other_qubit) haha.

@mtreinish mtreinish added this pull request to the merge queue Sep 11, 2024
@mtreinish
Copy link
Member

The 1000 qubit QV circuit reproducer from #13081 works with this applied so I'm good to merge this.

Merged via the queue into Qiskit:main with commit f2ca920 Sep 11, 2024
15 checks passed
mergify bot pushed a commit that referenced this pull request Sep 11, 2024
* Fix edge case in Sabre release valve

If a Sabre trial does not find a set of Swaps to route nodes, the "release valve" adds Swaps to route the two-qubit gate in between the the closest two qubits. In rare cases, this leads to _more_ than one gate being routable, which was not handled correctly previously.

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>

* add reno and test

* Use sensible syntax

Co-authored-by: Kevin Hartman <kevin@hart.mn>

* Use sensible grammar

Co-authored-by: Kevin Hartman <kevin@hart.mn>

* clippy

* Check if the new test breaks CI

* Revert "Check if the new test breaks CI"

This reverts commit 01bcdc7.

---------

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
Co-authored-by: Kevin Hartman <kevin@hart.mn>
(cherry picked from commit f2ca920)
github-merge-queue bot pushed a commit that referenced this pull request Sep 11, 2024
* Fix edge case in Sabre release valve

If a Sabre trial does not find a set of Swaps to route nodes, the "release valve" adds Swaps to route the two-qubit gate in between the the closest two qubits. In rare cases, this leads to _more_ than one gate being routable, which was not handled correctly previously.

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>

* add reno and test

* Use sensible syntax

Co-authored-by: Kevin Hartman <kevin@hart.mn>

* Use sensible grammar

Co-authored-by: Kevin Hartman <kevin@hart.mn>

* clippy

* Check if the new test breaks CI

* Revert "Check if the new test breaks CI"

This reverts commit 01bcdc7.

---------

Co-authored-by: Jake Lishman <jake.lishman@ibm.com>
Co-authored-by: Kevin Hartman <kevin@hart.mn>
(cherry picked from commit f2ca920)

Co-authored-by: Julien Gacon <jules.gacon@googlemail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: Bugfix Include in the "Fixed" section of the changelog stable backport potential The bug might be minimal and/or import enough to be port to stable
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Panic in SabreLayout when running on large quantum volume circuit
6 participants