Skip to content

Commit

Permalink
Merge branch 'feat/cz' into feat/commutation
Browse files Browse the repository at this point in the history
  • Loading branch information
ss2165 committed Sep 20, 2023
2 parents 46fd4f8 + f37ebb9 commit 0d875b7
Show file tree
Hide file tree
Showing 50 changed files with 11,615 additions and 1,459 deletions.
2 changes: 1 addition & 1 deletion .github/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ then
exit 1
fi

if ! cargo clippy --all-targets --features="pyo3,portmatching" -- -D warnings
if ! cargo clippy --all-targets --features="pyo3,portmatching" --workspace -- -D warnings
then
echo "There are some clippy issues."
exit 1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy --all-targets --features="$FEATURES" -- -D warnings
run: cargo clippy --all-targets --features="$FEATURES" --workspace -- -D warnings
- name: Build docs
run: cargo doc --no-deps --features="$FEATURES"
env:
Expand Down
17 changes: 11 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ lazy_static = "1.4.0"
cgmath = "0.18.0"
num-rational = "0.4"
num-complex = { version = "0.4", optional = true }
tket-json-rs = { git = "https://github.com/CQCL/tket-json-rs", rev = "619db15d3", features = [
"tket2ops",
] }
tket-json-rs = { workspace = true }
rayon = "1.5"
tket-rs = { optional = true, git = "https://github.com/CQCL-DEV/tket-rs", rev = "bd7e8e04" }
thiserror = "1.0.28"
Expand All @@ -41,6 +39,10 @@ strum = "0.25.0"
fxhash = "0.2.1"
rmp-serde = { version = "1.1.2", optional = true }
delegate = "0.10.0"
csv = { version = "1.2.2" }
chrono = { version ="0.4.30" }
bytemuck = "1.14.0"
stringreader = "0.1.1"

[features]
pyo3 = [
Expand All @@ -65,11 +67,14 @@ harness = false

[workspace]

members = ["pyrs", "compile-matcher"]
members = ["pyrs", "compile-matcher", "taso-optimiser"]

[workspace.dependencies]

quantinuum-hugr = { git = "https://github.com/CQCL-DEV/hugr", rev = "abfaba6" }
portgraph = { version = "0.8", features = ["serde"] }
quantinuum-hugr = { git = "https://github.com/CQCL-DEV/hugr", rev = "660fef6e" }
portgraph = { version = "0.9", features = ["serde"] }
pyo3 = { version = "0.19" }
itertools = { version = "0.11.0" }
tket-json-rs = { git = "https://github.com/CQCL/tket-json-rs", rev = "619db15d3", features = [
"tket2ops",
] }
8 changes: 8 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ stable available.
cargo +nightly miri test
```

To run the python tests, run:

```bash
cd pyrs
maturin develop
pytest
```

## 💅 Coding Style

The rustfmt tool is used to enforce a consistent rust coding style. The CI will fail if the code is not formatted correctly. Python code is formatted with black.
Expand Down
4 changes: 2 additions & 2 deletions benches/benchmarks/hash.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use criterion::{black_box, criterion_group, AxisScale, BenchmarkId, Criterion, PlotConfiguration};
use hugr::hugr::views::SiblingGraph;
use hugr::hugr::views::{HierarchyView, SiblingGraph};
use hugr::HugrView;
use tket2::circuit::{CircuitHash, HierarchyView};
use tket2::circuit::CircuitHash;

use super::generators::make_cnot_layers;

Expand Down
4 changes: 2 additions & 2 deletions compile-matcher/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use itertools::Itertools;

use tket2::json::load_tk1_json_file;
// Import the PatternMatcher struct and its methods
use tket2::passes::taso::load_eccs_json_file;
use tket2::optimiser::taso::load_eccs_json_file;
use tket2::portmatching::{CircuitPattern, PatternMatcher};

/// Program to precompile patterns from files into a PatternMatcher stored as binary file.
Expand Down Expand Up @@ -65,7 +65,7 @@ fn main() {
let patterns = all_circs
.iter()
.filter_map(|circ| {
let circ: SiblingGraph<'_, DfgID> = SiblingGraph::new(&circ, circ.root());
let circ: SiblingGraph<'_, DfgID> = SiblingGraph::new(circ, circ.root());
// Fail silently on empty or disconnected patterns
CircuitPattern::try_from_circuit(&circ).ok()
})
Expand Down
54 changes: 54 additions & 0 deletions pyrs/src/circuit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Circuit-related functionality and utilities.
#![allow(unused)]

use pyo3::prelude::*;

use hugr::{Hugr, HugrView};
use tket2::extension::REGISTRY;
use tket2::json::TKETDecode;
use tket_json_rs::circuit_json::SerialCircuit;

/// Apply a fallible function expecting a hugr on a pytket circuit.
pub fn try_with_hugr<T, E, F>(circ: Py<PyAny>, f: F) -> PyResult<T>
where
E: Into<PyErr>,
F: FnOnce(Hugr) -> Result<T, E>,
{
let hugr = SerialCircuit::_from_tket1(circ).decode()?;
(f)(hugr).map_err(|e| e.into())
}

/// Apply a function expecting a hugr on a pytket circuit.
pub fn with_hugr<T, F: FnOnce(Hugr) -> T>(circ: Py<PyAny>, f: F) -> PyResult<T> {
try_with_hugr(circ, |hugr| Ok::<T, PyErr>((f)(hugr)))
}

/// Apply a hugr-to-hugr function on a pytket circuit, and return the modified circuit.
pub fn try_update_hugr<E: Into<PyErr>, F: FnOnce(Hugr) -> Result<Hugr, E>>(
circ: Py<PyAny>,
f: F,
) -> PyResult<Py<PyAny>> {
let hugr = try_with_hugr(circ, f)?;
SerialCircuit::encode(&hugr)?.to_tket1()
}

/// Apply a hugr-to-hugr function on a pytket circuit, and return the modified circuit.
pub fn update_hugr<F: FnOnce(Hugr) -> Hugr>(circ: Py<PyAny>, f: F) -> PyResult<Py<PyAny>> {
let hugr = with_hugr(circ, f)?;
SerialCircuit::encode(&hugr)?.to_tket1()
}

#[pyfunction]
pub fn validate_hugr(c: Py<PyAny>) -> PyResult<()> {
try_with_hugr(c, |hugr| hugr.validate(&REGISTRY))
}

#[pyfunction]
pub fn to_hugr_dot(c: Py<PyAny>) -> PyResult<String> {
with_hugr(c, |hugr| hugr.dot_string())
}

#[pyfunction]
pub fn to_hugr(c: Py<PyAny>) -> PyResult<Hugr> {
with_hugr(c, |hugr| hugr)
}
102 changes: 51 additions & 51 deletions pyrs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,71 +1,71 @@
use hugr::{hugr::views::SiblingGraph, ops::handle::DfgID, Hugr, HugrView};
use pyo3::{exceptions::PyTypeError, prelude::*};
use tket2::{
circuit::HierarchyView,
json::TKETDecode,
passes::apply_greedy_commutation,
portmatching::{CircuitPattern, PatternMatcher},
};
//! Python bindings for TKET2.
#![warn(missing_docs)]
use hugr::Hugr;
use pyo3::prelude::*;
use tket2::{json::TKETDecode, passes::apply_greedy_commutation};
use tket_json_rs::circuit_json::SerialCircuit;

use tket2::extension::REGISTRY;
use tket2::portmatching::pyo3::PyValidateError;
mod circuit;

#[pyfunction]
fn check_soundness(c: Py<PyAny>) -> PyResult<()> {
let ser_c = SerialCircuit::_from_tket1(c);
let hugr: hugr::Hugr = ser_c.decode().unwrap();
hugr.validate(&REGISTRY)
.map_err(|e| PyValidateError::new_err(e.to_string()))
}

#[pyfunction]
fn to_hugr_dot(c: Py<PyAny>) -> PyResult<String> {
let ser_c = SerialCircuit::_from_tket1(c);
let hugr: Hugr = ser_c.decode().unwrap();
Ok(hugr.dot_string())
}

#[pyfunction]
fn to_hugr(c: Py<PyAny>) -> PyResult<Hugr> {
let ser_c = SerialCircuit::_from_tket1(c);
let hugr: Hugr = ser_c.decode().unwrap();
Ok(hugr)
}

fn pyerr_string<T: std::fmt::Debug>(e: T) -> PyErr {
PyErr::new::<PyTypeError, _>(format!("{:?}", e))
}
#[pyfunction]
fn greedy_depth_reduce(py_c: PyObject) -> PyResult<(PyObject, u32)> {
let s_c = SerialCircuit::_from_tket1(py_c.clone());
let mut h: Hugr = s_c.decode().map_err(pyerr_string)?;
let n_moves = apply_greedy_commutation(&mut h).map_err(pyerr_string)?;
let circ: SiblingGraph<'_, DfgID> = SiblingGraph::new(&h, h.root());
let mut h: Hugr = s_c.decode()?;
let n_moves = apply_greedy_commutation(&mut h)?;

let s_c = SerialCircuit::encode(&circ).map_err(pyerr_string)?;
let s_c = SerialCircuit::encode(&h)?;
Ok((s_c.to_tket1()?, n_moves))
}

/// The Python bindings to TKET2.
#[pymodule]
fn pyrs(py: Python, m: &PyModule) -> PyResult<()> {
add_patterns_module(py, m)?;
add_circuit_module(py, m)?;
add_pattern_module(py, m)?;
add_pass_module(py, m)?;
m.add_function(wrap_pyfunction!(to_hugr_dot, m)?)?;
m.add_function(wrap_pyfunction!(to_hugr, m)?)?;

m.add("ValidateError", py.get_type::<PyValidateError>())?;
m.add_function(wrap_pyfunction!(check_soundness, m)?)?;
Ok(())
}

fn add_patterns_module(py: Python, parent: &PyModule) -> PyResult<()> {
let m = PyModule::new(py, "patterns")?;
m.add_class::<CircuitPattern>()?;
m.add_class::<PatternMatcher>()?;
parent.add_submodule(m)?;
Ok(())
/// circuit module
fn add_circuit_module(py: Python, parent: &PyModule) -> PyResult<()> {
let m = PyModule::new(py, "circuit")?;
m.add_class::<tket2::T2Op>()?;
m.add_class::<tket2::Pauli>()?;

m.add("HugrError", py.get_type::<hugr::hugr::PyHugrError>())?;
m.add("BuildError", py.get_type::<hugr::builder::PyBuildError>())?;
m.add(
"ValidationError",
py.get_type::<hugr::hugr::validate::PyValidationError>(),
)?;
m.add(
"HUGRSerializationError",
py.get_type::<hugr::hugr::serialize::PyHUGRSerializationError>(),
)?;
m.add(
"OpConvertError",
py.get_type::<tket2::json::PyOpConvertError>(),
)?;

parent.add_submodule(m)
}

/// portmatching module
fn add_pattern_module(py: Python, parent: &PyModule) -> PyResult<()> {
let m = PyModule::new(py, "pattern")?;
m.add_class::<tket2::portmatching::CircuitPattern>()?;
m.add_class::<tket2::portmatching::PatternMatcher>()?;

m.add(
"InvalidPatternError",
py.get_type::<tket2::portmatching::pattern::PyInvalidPatternError>(),
)?;
m.add(
"InvalidReplacementError",
py.get_type::<hugr::hugr::views::sibling_subgraph::PyInvalidReplacementError>(),
)?;

parent.add_submodule(m)
}

fn add_pass_module(py: Python, parent: &PyModule) -> PyResult<()> {
Expand Down
119 changes: 0 additions & 119 deletions pyrs/src/libcopuy

This file was deleted.

Loading

0 comments on commit 0d875b7

Please sign in to comment.