Skip to content

Commit

Permalink
Make dense layout algorithm deterministic when run in parallel (#13133)
Browse files Browse the repository at this point in the history
* Make dense layout algorithm deterministic when run in parallel

The dense layout algorithm is trying to find the densest k subgraph of
the connectivity graph. To do this it performs a BFS from each node in
the in graph of k nodes to determine the subgraph with the most number
of edges. But in cases of ties where there are subgraphs with the same
number of edges the exact output would be determined by the iteration
order that we're evaluating a BFS search. However, this algorithm runs
in parallel in most cases and the exact iteration order isn't going to
be stable when running in parallel. It will depend on which threads
finish first. This commit fixes this potential non-determinism in the
algorithm by defaulting to the lower node index's trial results instead
of relying on the execution order. This should mean we return identical
results regardless of how many threads are run or how quickly they
execute.

* Add release note

* Also handle the use_error case too

(cherry picked from commit 65bb09e)
  • Loading branch information
mtreinish authored and mergify[bot] committed Sep 19, 2024
1 parent 97f4f6d commit c60fcf0
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
9 changes: 7 additions & 2 deletions crates/accelerate/src/dense_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct SubsetResult {
pub error: f64,
pub map: Vec<usize>,
pub subgraph: Vec<[usize; 2]>,
pub index: usize,
}

fn bfs_sort(adj_matrix: ArrayView2<f64>, start: usize, num_qubits: usize) -> Vec<usize> {
Expand Down Expand Up @@ -190,6 +191,7 @@ pub fn best_subset_inner(
error,
map: bfs,
subgraph,
index: k,
}
};

Expand All @@ -199,17 +201,20 @@ pub fn best_subset_inner(
map: Vec::new(),
error: f64::INFINITY,
subgraph: Vec::new(),
index: usize::MAX,
}
};

let reduce_fn = |best: SubsetResult, curr: SubsetResult| -> SubsetResult {
if use_error {
if curr.count >= best.count && curr.error < best.error {
if (curr.count >= best.count && curr.error < best.error)
|| (curr.count == best.count && curr.error == best.error && curr.index < best.index)
{
curr
} else {
best
}
} else if curr.count > best.count {
} else if curr.count > best.count || (curr.count == best.count && curr.index < best.index) {
curr
} else {
best
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Fixed a potential source of non-determinism in :class:`~.DenseLayout` (and
by extension :class:`~.SabreLayout`) when targeting a
:class:`.CouplingMap` or :class:`.Target` that has more than one subgraph
with the same degree of connectivity. In these case the exact output
layout from the pass could previously fluctuate based on the number of
local CPUs and thread execution speed.

0 comments on commit c60fcf0

Please sign in to comment.