Add structural equality check for DAGCircuit
#14762
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The current implementation of equality (the Python-facing
DAGCircuit.__eq__
) is a semantic-equality checker. This is typically what users care about. Transpiler-pass authors, however, need to care about determinism in the order of modifications of a DAG, including normally internal details such as the precise set ofNodeIndex
es that are populated, or the order the edges are traversed for any given node.This commit adds a new method,
DAGCircuit::structurally_equal
, which checks the node and edge lists of the graph structure for exact equality (slightly indirectly, sincepetgraph
doesn't let us access the internal details of theStableGraph
struct directly), to help verify whether two DAGs have gone through the same order of modifications.Summary
Details and comments
This needs tests but I wanted to push it for comment before I spend the time writing them, since it's implying strong requirements on determinism for passes. Currently, Rust-space Sabre (since #14317) appears non-deterministic on some ASV benchmarks, but this is because it directly iterates over the internal graph structure (the node and edge lists), which are modified in a non-deterministic order by
CommutativeCancellation
. The check function in this PR is how I tracked down the non-determinism, using a pretty hacky recipe such as: