mirror of https://github.com/Qiskit/qiskit.git
Make dense layout algorithm deterministic when run in parallel (#13133)
* 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
This commit is contained in:
parent
2245a4f44b
commit
65bb09efab
|
@ -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> {
|
||||
|
@ -190,6 +191,7 @@ pub fn best_subset_inner(
|
|||
error,
|
||||
map: bfs,
|
||||
subgraph,
|
||||
index: k,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue