Skip to content

Commit

Permalink
Further oxidize sabre (#8388)
Browse files Browse the repository at this point in the history
* Further oxidize sabre

In #7977 we started the process of oxidizing SabreSwap by replacing the
inner-most scoring heuristic loop with a rust routine. This greatly
improved the overall performance and scaling of the transpiler pass.
Continuing from where that started this commit migrates more of the pass
into the Rust domain so that almost all the pass's operations are done
inside a rust module and all that is returned is a list of swaps to run
prior to each 2q gate. This should further improve the runtime
performance of the pass and scaling because the only steps performed in
Python are generating the input data structures and then replaying the
circuit with SWAPs inserted at the appropriate points.

While we could have stuck with #7977 as the performance of the pass was
more than sufficient after it. What this commit really enables by moving
most of the pass to the rust domain is to expand with improvments and
expansion of the sabre algorithm which will require multithreaded to be
efficiently implemented. So while this will have some modest performance
improvements this is more about setting the stage for introducing
variants of SabreSwap that do more thorough analysis in the future
(which were previously preculded by the parallelism limitations of python).

* Fix most test failures

This commit fixes a small typo/logic error in the algorithm
implementation that was preventing sabre from making forward progress
because it wasn't correctly identifying successors for the next layer.
By fixing this all the hard errors in the SabreSwap tests are fixed. The
only failures left seem to be related to a different layout which
hopefully is not a correctness issue but just caused by different
ordering.

* Rework circuit reconstruction to use layer order

In some tests there were subtle differences in the relative positioning
of the 1q gates relative to inserted swaps (i.e. a 1q gate which was
before the swap previously could move to after it). This was caused by
different topological ordering being used between the hybrid python sabre
implementation and the mostly rust sabre implementations. To ensure a
consistent ordering fater moving mostly to rust this changes the
swap insertion loop to iterate over the circuit layers which mirrors how
the old sabre implementation worked.

* Differentiate between empty extended_set and none

* Simplify arguments passing to remove adjacency matrix storage

* Only check env variables once in rust

* Rust side NLayout.copy()

* Preserve SabreSwap execution order

This commit fixes an issue where in some cases the topological order the
DAGCircuit is traversed is different from the topological order that
sabre uses internally. The build_swap_map sabre swap function is only
valid if the 2q gates are replayed in the same exact order when
rebuilding the DAGCircuit. If a 2q gate gets replayed in a different
order the layout mapping will cause the circuit to diverge and
potentially be invalid. This commit updates the replay logic in the
python side to detect when the topological order over the dagcircuit
differs from the sabre traversal order and attempts to correct it.

* Rework SabreDAG to include full DAGCircuit structure

Previously we attempted to just have the rust component of sabre deal
solely with the 2q component of the input circuit. However, while this
works for ~80% of the cases it fails to account ordering and
interactions between non-2q gates or instructions with classical bits.
To address this the sabre dag structure is modified to contain all
isntructions in the input circuit and structurally match the
DAGCircuit's edges. This fixes most of the issues related to gate
ordering the previous implementation was encountering. It also
simplifies the swap insertion/replay of the circuit in the python side
as we now get an exact application order from the rust code.

* Switch back to topological_op_nodes() for SabreDAG creation

* Fix lint

* Fix extended set construction

* Fix typo in application of decay rate

* Remove unused QubitsDecay class

* Remove unused EdgeList class

* Remove unnecessary SabreRNG class

* Cleanup SabreDAG docstring and comments

* Remove unused edge weights from SabreDAG

The edge weights in the SabreDAG struct were set to the qubit indices
from the input DAGCircuit because the edges represent the flow of data
on the qubit. However, we never actually inspect the edge weights and
all having them present does is use extra memory. This commit changes
SabreDAG to just not set any weight for edges as all we need is the
source and target nodes for the algorithm to work.

* s/_bit_indices/_qubit_indices/g

* Fix sabre rust class signatures
  • Loading branch information
mtreinish authored Aug 22, 2022
1 parent 93e2fc5 commit 8ce6e0a
Show file tree
Hide file tree
Showing 11 changed files with 517 additions and 537 deletions.
106 changes: 73 additions & 33 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ rand_distr = "0.4.3"
ahash = "0.8.0"
num-complex = "0.4"
num-bigint = "0.4"
retworkx-core = "0.11"

[dependencies.pyo3]
version = "0.16.5"
Expand Down
Loading

0 comments on commit 8ce6e0a

Please sign in to comment.