Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Initial support for matrix inverse in qdk_sim_experimental crate #920

Merged
merged 14 commits into from
Apr 8, 2022
Merged
75 changes: 45 additions & 30 deletions src/Simulation/qdk_sim_rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@
# Licensed under the MIT License.

[package]
name = "qdk_sim_experimental"
name = "qdk_sim_rs"
version = "0.0.1-alpha"
authors = ["Microsoft"]
edition = "2018"
license = "MIT"
description = "Experimental simulators for use with the Quantum Development Kit."
description = "Rust-based simulators for use with the Quantum Development Kit."
homepage = "https://github.com/microsoft/qsharp-runtime"
repository = "https://github.com/microsoft/qsharp-runtime"
readme = "README.md"

# Verified with cargo-msrv.
rust-version = "1.51.0"

exclude = [
# Exclude files specific to QDK build pipelines.
"*.template", "*.csx", "*.ps1", "NuGet.Config", "drop",
Expand All @@ -21,72 +24,84 @@ exclude = [
"*.egg-info", "qdk_sim_experimental", "setup.py", "*.whl", "pyproject.toml"
]

# Enable LaTeX on docs.rs.
# See https://stackoverflow.com/a/54573800/267841 and
# https://github.com/rust-num/num/pull/226/files for why this works.
[package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "docs-includes/header.html", "--html-after-content", "docs-includes/after.html" ]
features = ["document-features"]

[lib]
crate-type = ["rlib", "staticlib", "cdylib"]
name = "qdk_sim"
path = "src/lib.rs"
crate-type = ["rlib", "staticlib", "cdylib"]

# Optional build-time features: we use this to create Python and WASM bindings.
[features]
default = []
wasm = ["web-sys"]

# When Python bindings are enabled, we also need the pyo3 dependency.
## Enables Python bindings for this crate.
python = ["pyo3", "numpy"]

# Enable LaTeX on docs.rs.
# See https://stackoverflow.com/a/54573800/267841 and
# https://github.com/rust-num/num/pull/226/files for why this works.
[package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "docs-includes/header.html", "--html-after-content", "docs-includes/after.html" ]
## Ensures that the crate is compatible with usage from WebAssembly.
wasm = ["web-sys"]


[profile.release]
opt-level = 3
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
opt-level = 3
panic = 'unwind'

[dependencies]
ndarray = { version = "0.15.2", features = ["serde"] }
num-complex = { version = "0.4", features = ["serde"] }
num-traits = "0.2"
derive_more = "0.99.10"
itertools = "0.9.0"
rand = { version = "0.7.3", features = ["alloc"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
lazy_static = "1.4.0"
anyhow = "1.0.56"
# We use built to expose compile-time metadata about how this crate
# was built to C and Rust callers.
built = "0.5.0"
cauchy = "0.4.0"
cfg-if = "1.0.0"
num_enum = "0.5.1"
derive_more = "0.99.10"
# We use document-features to automatically generate feature documentation from
# Cargo.toml, following the example at
cgranade marked this conversation as resolved.
Show resolved Hide resolved
document-features = { version = "0.2", optional = true }
# See https://github.com/rust-random/rand/issues/990
# and https://docs.rs/getrandom/0.1.15/getrandom/index.html#support-for-webassembly-and-asmjs
# for why this is needed.
# NB: We depend on 0.1.15, since that's what gets brought in transitively
# by rand and rand_core.
getrandom = { version = "0.1.15", features = ["wasm-bindgen"] }

# We only need web-sys when compiling with the wasm feature.
web-sys = { version = "0.3.4", features = ['console'], optional = true }

itertools = "0.9.0"
lazy_static = "1.4.0"
miette = "4.3.0"
ndarray = { version = "0.15.2", features = ["serde"] }
num-complex = { version = "0.4", features = ["serde"] }
num-traits = "0.2"
num_enum = "0.5.1"
numpy = { version = "0.13.1", optional = true }
# We only need PyO3 when generating Python bindings.
pyo3 = { version = "0.13.2", features = ["extension-module"], optional = true }
numpy = {version = "0.13.1", optional = true}
rand = { version = "0.7.3", features = ["alloc"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0.30"

# We use built to expose compile-time metadata about how this crate
# was built to C and Rust callers.
built = "0.5.0"
# We only need web-sys when compiling with the wasm feature.
web-sys = { version = "0.3.4", features = ['console'], optional = true }

[build-dependencies]
built = "0.5.0"


[dev-dependencies]
approx = { version = "0.5.1", features = ["num-complex"] }
assert-json-diff = "2.0.1"
criterion = { version = "0.3", features = ['html_reports', 'csv_output'] }
ndarray = { version = "0.15.4", features = ["approx"] }

[[bench]]
name = "c_api_benchmark"
harness = false
name = "c_api_benchmark"

[[bench]]
name = "microbenchmark"
harness = false
name = "microbenchmark"
9 changes: 3 additions & 6 deletions src/Simulation/qdk_sim_rs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
To generate and view the documentation for this crate locally, please
run:

$ cargo +nightly doc --features python --open
$ cargo doc --features python,document-features --open
-->

# Quantum Development Kit Preview Simulators
Expand All @@ -28,11 +28,6 @@ The [`c_api`] module allows for using the simulation functionality in this crate

Similarly, the [`python`] module allows exposing data structures in this crate to Python programs.

## Cargo Features

- **`python`**: Enables Python bindings for this crate.
- **`wasm`**: Ensures that the crate is compatible with usage from WebAssembly.

## Representing quantum systems

This crate provides several different data structures for representing quantum systems in a variety of different conventions:
Expand Down Expand Up @@ -148,3 +143,5 @@ TODO
- Stabilizer simulation not yet exposed via C API.
- Test and microbenchmark coverage still incomplete.
- Too many APIs `panic!` or `unwrap`, and need replaced with `Result` returns instead.

# Crate features
cgranade marked this conversation as resolved.
Show resolved Hide resolved
66 changes: 65 additions & 1 deletion src/Simulation/qdk_sim_rs/benches/microbenchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
//! In particular, optimizing these benchmarks may not translate into improved
//! performance in user code.

use cauchy::c64;
use criterion::{criterion_group, criterion_main, Criterion};
use ndarray::array;
use qdk_sim::{
common_matrices,
common_matrices::nq_eye,
linalg::{extend_one_to_n, extend_two_to_n, Tensor},
linalg::{extend_one_to_n, extend_two_to_n, Inv, Tensor},
};

fn linalg(c: &mut Criterion) {
Expand Down Expand Up @@ -79,6 +81,68 @@ fn linalg(c: &mut Criterion) {
let _result = cnot.tensor(&x);
})
});
group.bench_function("inv 4x4 f64", |b| {
let x = array![
[
0.23935896217435304,
0.34333031120985236,
0.8201953415286973,
0.8074588350909441
],
[
0.11957583380425751,
0.16906445210054732,
0.21728173861409317,
0.7120594445167554
],
[
0.04023516190513021,
0.9635112441739464,
0.9209190516642924,
0.114251355434274
],
[
0.8749507948480983,
0.2661348079904513,
0.17485566324545554,
0.2934138616881069
],
];
b.iter(|| {
let _inv = x.inv();
});
});
group.bench_function("inv 4x4 c64", |b| {
let x = array![
[
c64::new(0.30874277550419704, 0.8167808814398533),
c64::new(0.9303782008146939, 0.8925538040143673),
c64::new(0.11573522743286513, 0.6357551264716991),
c64::new(0.7869240102858357, 0.28376515716360073)
],
[
c64::new(0.9638410081049803, 0.4460520369459663),
c64::new(0.043516097874141346, 0.1652124014187376),
c64::new(0.05938096491956191, 0.7696366269843138),
c64::new(0.9636976605227736, 0.8125701401805293)
],
[
c64::new(0.9548859426476123, 0.7825350828251003),
c64::new(0.4223649577868721, 0.4522018603906839),
c64::new(0.36001119456757835, 0.22138920205104395),
c64::new(0.0044511389785256705, 0.14148562531641973)
],
[
c64::new(0.6066852151129799, 0.5140547256960247),
c64::new(0.23439110687939924, 0.3064074735518828),
c64::new(0.9963759728056912, 0.401859040365666),
c64::new(0.7176238235495955, 0.3948597214947167)
],
];
b.iter(|| {
let _inv = x.inv();
});
});
group.finish();
}

Expand Down
Loading