Skip to content
This repository was 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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 46 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,85 @@ 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
# https://docs.rs/document-features/latest/document_features#examples.
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"
10 changes: 4 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,6 @@ 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
<!-- Note that this section is filled in automatically by document-features. -->
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