Skip to content

Commit

Permalink
Implement multithreaded stochastic swap in rust
Browse files Browse the repository at this point in the history
This commit is a rewrite of the core swap trials functionality in the
StochasticSwap transpiler pass. Previously this core routine was written
using Cython (see #1789) which had great performance, but that
implementation was single threaded. The core of the stochastic swap
algorithm by it's nature is well suited to be executed in parallel, it
attempts a number of random trials and then picks the best result
from all the trials and uses that for that layer. These trials can
easily be run in parallel as there is no data dependency between the
trials (there are shared inputs but read-only). As the algorithm
generally scales exponentially the speed up from running the trials in
parallel can offset this and improve the scaling of the pass. Running
the pass in parallel was previously tried in #4781 using Python
multiprocessing but the overhead of launching an additional process and
serializing the input arrays for each trial was significantly larger
than the speed gains. To run the algorithm efficiently in parallel
multithreading is needed to leverage shared memory on shared inputs.

This commit rewrites the cython routine using rust. This was done for
two reasons. The first is that rust's safety guarantees make dealing
with and writing parallel code much easier and safer. It's also
multiplatform because the rust language supports native threading
primatives in language. The second is while writing parallel cython
code using open-mp there are limitations with it, mainly on windows. In
practice it was also difficult to write and maintain parallel cython
code as it has very strict requirements on python and c code
interactions. It was much faster and easier to port it to rust and the
performance for each iteration (outside of parallelism) is the same (in
some cases marginally faster) in rust. The implementation here reuses
the data structures that the previous cython implementation introduced
(mainly flattening all the terra objects into 1d or 2d numpy arrays for
efficient access from C).

The speedups from this PR can be significant, calling transpile() on a
400 qubit (with a depth of 10) QV model circuit targetting a 409 heavy
hex coupling map goes from ~200 seconds with the single threaded cython
to ~60 seconds with this PR locally on a 32 core system, When transpiling
a 1000 qubit (also with a depth of 10) QV model circuit targetting a 1081
qubit heavy hex coupling map goes from taking ~6500 seconds to ~720
seconds.

The tradeoff with this PR is for local qiskit-terra development a rust
compiler needs to be installed. This is made trivial using rustup
(https://rustup.rs/), but it is an additional burden and one that we
might not want to make. If so we can look at turning this PR into a
separate repository/package that qiskit-terra can depend on. The
tradeoff here is that we'll be adding friction to the api boundary
between the pass and the core swap trials interface. But, it does ease
the dependency on development for qiskit-terra.
  • Loading branch information
mtreinish committed Feb 14, 2022
1 parent 1ae663d commit 9d9c2dc
Show file tree
Hide file tree
Showing 14 changed files with 466 additions and 500 deletions.
33 changes: 33 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "qiskit-terra"
version = "0.20.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
name = "qiskit"
crate-type = ["cdylib"]

[dependencies]
rayon = "1.5"
numpy = "0.15.1"
rand = "0.8"
rand_pcg = "0.3"
rand_distr = "0.4.3"

[dependencies.pyo3]
version = "0.15.1"
features = ["extension-module", "hashbrown"]

[dependencies.ndarray]
version = "^0.15.0"
features = ["rayon"]

[dependencies.hashbrown]
version = "0.11.2"
features = ["rayon"]

[profile.release]
lto = 'fat'
codegen-units = 1
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ include test/python/pickles/*.pickle
include test/python/qasm/*.qasm
include test/python/visualization/references/*.png
include test/python/notebooks/*.ipynb

include Cargo.toml
recursive-include src *
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[build-system]
requires = ["Cython>=0.27.1", "setuptools", "wheel"]
requires = ["Cython>=0.27.1", "setuptools", "wheel", "setuptools-rust"]
build-backend = "setuptools.build_meta"

[tool.black]
line-length = 100
Expand Down
13 changes: 0 additions & 13 deletions qiskit/transpiler/passes/routing/cython/__init__.py

This file was deleted.

This file was deleted.

194 changes: 0 additions & 194 deletions qiskit/transpiler/passes/routing/cython/stochastic_swap/swap_trial.pyx

This file was deleted.

43 changes: 0 additions & 43 deletions qiskit/transpiler/passes/routing/cython/stochastic_swap/utils.pxd

This file was deleted.

Loading

0 comments on commit 9d9c2dc

Please sign in to comment.