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

Make dense layout algorithm deterministic when run in parallel #13133

Merged

Conversation

mtreinish
Copy link
Member

Summary

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.

Details and comments

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.
@mtreinish mtreinish requested a review from a team as a code owner September 11, 2024 15:57
@qiskit-bot
Copy link
Collaborator

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

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

@mtreinish mtreinish added Changelog: Bugfix Include in the "Fixed" section of the changelog Rust This PR or issue is related to Rust code in the repository mod: transpiler Issues and PRs related to Transpiler stable backport potential The bug might be minimal and/or import enough to be port to stable labels Sep 11, 2024
@mtreinish mtreinish added this to the 1.2.1 milestone Sep 11, 2024
@henryzou50 henryzou50 self-assigned this Sep 11, 2024
@coveralls
Copy link

coveralls commented Sep 11, 2024

Pull Request Test Coverage Report for Build 10820177047

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

  • 5 of 5 (100.0%) changed or added relevant lines in 1 file are covered.
  • 20 unchanged lines in 3 files lost coverage.
  • Overall coverage increased (+0.01%) to 88.846%

Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/lex.rs 2 92.23%
qiskit/transpiler/passes/synthesis/high_level_synthesis.py 6 96.73%
crates/qasm2/src/parse.rs 12 96.69%
Totals Coverage Status
Change from base Build 10814219623: 0.01%
Covered Lines: 73101
Relevant Lines: 82278

💛 - Coveralls

Copy link
Contributor

@henryzou50 henryzou50 left a comment

Choose a reason for hiding this comment

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

LGTM! This resolves the non-determinism issue in the reduce_fn function. By introducing the index field in the SubsetResult struct, the comparison now has a consistent tie-breaking mechanism when count values are equal. The index ensures that, even when multiple subgraphs have the same number of edges, the result is deterministic, as the subgraph with the lower index is always chosen.

This removes the dependency on thread execution speed and order, making the function’s behavior predictable in parallel environments. Thanks!

@henryzou50
Copy link
Contributor

henryzou50 commented Sep 11, 2024

Some notes after reviewing it again. Need to add release notes and add a check for the error aware case.

@mtreinish
Copy link
Member Author

Some notes after reviewing it again. Need to add release notes and add a check for the error aware case.

Done in: 34a8287 and c3cf18e

@Cryoris Cryoris modified the milestones: 1.2.1, 1.2.2 Sep 12, 2024
@jakelishman jakelishman added this pull request to the merge queue Sep 19, 2024
Merged via the queue into Qiskit:main with commit 65bb09e Sep 19, 2024
15 checks passed
mergify bot pushed a commit that referenced this pull request Sep 19, 2024
* 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)
github-merge-queue bot pushed a commit that referenced this pull request Sep 19, 2024
… (#13190)

* 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)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
github-merge-queue bot pushed a commit that referenced this pull request Sep 19, 2024
… (#13190)

* 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)

Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
@mtreinish mtreinish deleted the fix-non-determinism-in-dense-layout branch September 20, 2024 00:09
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 mod: transpiler Issues and PRs related to Transpiler Rust This PR or issue is related to Rust code in the repository 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.

6 participants