Skip to content

Commit

Permalink
Add structure for multiple Rust crates (Qiskit#9742)
Browse files Browse the repository at this point in the history
* Add structure for multiplie Rust extension crates

This is a precursor to adding an entirely separate and self-contained
crate to handle parsing of OpenQASM 2 (not 3 - this is kind of like a
trial run for that).  It could conceivably still live within
`qiskit._accelerate`, but having separate crates helps us enforce more
sane API barriers, and has improvements in the incremental build time
when working on only one of the Rust extensions.

The intent after this commit is still to have `qiskit._accelerate` as an
easy catch-all for accelerators for Python.  Developers should not need
to be concerned with defining a new crate for every new feature, and for
the most part `_accelerate` is still logically interoperative within
itself (for example, `NLayout` is used all over).  This is just laying
out the groundwork so more complex crate additions _can_ also be made.

Some of the niceties to do with Cargo workspaces only became stabilised
in Rust 1.64.  In particular, inheritance from the workspace root for
things like the package version, Rust version, and dependencies only
came in then.  For now, the `workspace.packages` key in the root
`Cargo.toml` is ignored with a small warning during the build, but I've
put it in place mostly to keep track of what we can change once the MSRV
becomes 1.64 or greater (likely not til at least Terra 0.26).

* Add README.md to crates/accelerate

* Correct licence metadata
  • Loading branch information
jakelishman authored Mar 7, 2023
1 parent 2553376 commit c6cd0d5
Show file tree
Hide file tree
Showing 28 changed files with 119 additions and 83 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ jobs:
stestr run
# We set the --source-dir to '.' because we want all paths to appear relative to the repo
# root (we need to combine them with the Python ones), but we only care about `grcov`
# keeping the `src/*` files; we don't care about coverage in dependencies.
grcov . --binary-path target/debug/ --source-dir . --output-type lcov --output-path rust.info --llvm --branch --parallel --keep-only 'src/*'
# keeping the `crates/*` files; we don't care about coverage in dependencies.
grcov . --binary-path target/debug/ --source-dir . --output-type lcov --output-path rust.info --llvm --branch --parallel --keep-only 'crates/*'
env:
QISKIT_TEST_CAPTURE_STREAMS: 1
QISKIT_PARALLEL: FALSE
Expand Down
84 changes: 42 additions & 42 deletions Cargo.lock

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

46 changes: 9 additions & 37 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,42 +1,14 @@
[package]
name = "qiskit-terra"
[workspace]
members = ["crates/*"]

# This has no meaning until we're on Rust 1.64, but once we get there, the subpackages will be able
# to inherit from this rather than needing to duplicate its content themselves. Until we get there,
# keep this in sync with each subpackage `Cargo.toml`'s `package` key.
[workspace.package]
version = "0.24.0"
edition = "2021"
# Keep in sync with README.md and rust-toolchain.toml.
rust-version = "1.61"

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

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

[dependencies]
rayon = "1.7"
numpy = "0.18.0"
rand = "0.8"
rand_pcg = "0.3"
rand_distr = "0.4.3"
ahash = "0.8.3"
num-complex = "0.4"
num-bigint = "0.4"
rustworkx-core = "0.12"

[dependencies.pyo3]
version = "0.18.1"
features = ["extension-module", "hashbrown", "num-complex", "num-bigint", "indexmap"]

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

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

[dependencies.indexmap]
version = "1.9"
features = ["rayon"]
rust-version = "1.61" # Keep in sync with README.md and rust-toolchain.toml.
license = "Apache-2.0"

[profile.release]
lto = 'fat'
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ include test/python/notebooks/*.ipynb

include Cargo.toml
include Cargo.lock
recursive-include src *
recursive-include crates *
41 changes: 41 additions & 0 deletions crates/accelerate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[package]
name = "qiskit_accelerate"
# The following options can be inherited with (e.g.) `version.workspace = true` once we hit Rust
# 1.64. Until then, keep in sync with the root `Cargo.toml`.
version = "0.24.0"
edition = "2021"
rust-version = "1.61"
license = "Apache-2.0"

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

[dependencies]
rayon = "1.7"
numpy = "0.18.0"
rand = "0.8"
rand_pcg = "0.3"
rand_distr = "0.4.3"
ahash = "0.8.3"
num-complex = "0.4"
num-bigint = "0.4"
rustworkx-core = "0.12"

# The base version of PyO3 and setting a minimum feature set (e.g. probably just 'extension-module')
# can be done in the workspace and inherited once we hit Rust 1.64.
[dependencies.pyo3]
version = "0.18.1"
features = ["extension-module", "hashbrown", "indexmap", "num-complex", "num-bigint"]

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

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

[dependencies.indexmap]
version = "1.9"
features = ["rayon"]
21 changes: 21 additions & 0 deletions crates/accelerate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# `qiskit._accelerate`

This crate provides a bits-and-pieces Python extension module for small, self-contained functions
that are used by the main Python-space components to accelerate certain tasks. If you're trying to
speed up one particular Python function by replacing its innards with a Rust one, this is the best
place to put the code. This is _usually_ the right place to put Rust/Python interfacing code.

The crate is made accessible as a private submodule, `qiskit._accelerate`. There are submodules
within that (largely matching the structure of the Rust code) mostly for grouping similar functions.

Some examples of when it might be more appropriate to start a new crate instead of using the
ready-made solution of `qiskit._accelerate`:

* The feature you are developing will have a large amount of domain-specific Rust code and is a
large self-contained module. If it reasonably works in a single Rust file, you probably just want
to put it here.

* The Rust code is for re-use within other Qiskit crates and maintainability of the code will be
helped by using the crate system to provide API boundaries between the different sections.

* You want to start writing your own procedural macros.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@
"Documentation": "https://qiskit.org/documentation/",
"Source Code": "https://github.com/Qiskit/qiskit-terra",
},
rust_extensions=[RustExtension("qiskit._accelerate", "Cargo.toml", binding=Binding.PyO3)],
rust_extensions=[
RustExtension("qiskit._accelerate", "crates/accelerate/Cargo.toml", binding=Binding.PyO3)
],
zip_safe=False,
entry_points={
"qiskit.unitary_synthesis": [
Expand Down

0 comments on commit c6cd0d5

Please sign in to comment.