Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
33276f6
Added gridsynth pass
Dec 9, 2025
0fa764e
Added rsgridsynth dependency
Dec 9, 2025
df9ad08
Declared gridsynth as module
Dec 9, 2025
c490e29
Finding angle node of guppy function but not extracting angle
Dec 10, 2025
a02ab9b
Extracting angle successfully
Dec 10, 2025
946f6b8
Added clean up when finding angle_node and angle
Dec 10, 2025
e7430cd
Removed commented out code
Dec 10, 2025
689f24c
Swithed to get_io from custom function
Dec 10, 2025
74ae91d
Working for simple guppy cases
Dec 11, 2025
0c14b7d
tidied up linting errors and commented out code
Dec 11, 2025
c59dbc4
Generalised to arbitry number of Rz gates
Dec 11, 2025
e2816cf
Added Python bindings
Dec 15, 2025
77c4e6d
Bindings no longer raising error in Python
Dec 15, 2025
e21532e
Added comment warning of rsgridsynth instability
Dec 15, 2025
9072afa
Updated rsgridsynth to new crates.io version
Dec 15, 2025
ae18726
Corrected formatting and linting errors
Dec 15, 2025
14fce82
just check now passin
Dec 15, 2025
9fef0b6
feat! Bump hugr to 0.25.0
aborgna-q Dec 16, 2025
4060c73
drive-by: Fix justfile setup
aborgna-q Dec 16, 2025
9ae7961
Update envelope / read errors
aborgna-q Dec 16, 2025
ee01fea
Update metadata method calls
aborgna-q Dec 16, 2025
350057b
SiblingSubgraph requires RootChecked
aborgna-q Dec 16, 2025
d572aa4
Extension definitions return an Arc rather than Weak<Extension>
aborgna-q Dec 16, 2025
ba45b19
Replace deprecated ReplaceTypes::replace_op
aborgna-q Dec 16, 2025
7944c50
inkwell breaking changes
aborgna-q Dec 16, 2025
91ead38
downgrade non-weak extensions
aborgna-q Dec 16, 2025
a193513
pyo3 breaking changes
aborgna-q Dec 16, 2025
45d5bc3
More deprecated fns
aborgna-q Dec 16, 2025
4844b87
More changes/deprecations
aborgna-q Dec 16, 2025
ecea580
drop op in replacer
aborgna-q Dec 16, 2025
13a21b4
rollback one of the replaceTypes fixes
aborgna-q Dec 16, 2025
b8210fa
fix unwrap
aborgna-q Dec 16, 2025
76e0059
one fewer deprecated call
aborgna-q Dec 16, 2025
2070eb5
last deprecated call
aborgna-q Dec 16, 2025
31e2338
Update snapshots
aborgna-q Dec 17, 2025
c3a04a6
feat: Remove order edges in NormalizeGuppy pass
aborgna-q Dec 17, 2025
59546a9
New tests added but one of them failing
Dec 17, 2025
493f1d1
Fixed bug: unable to handle 2 qubit gates
Dec 17, 2025
c78ad27
Added interpreting of x gates
Dec 18, 2025
01a6c84
Removed experimental steps and debugging lines
Dec 19, 2025
e5d5ba5
Merging
Dec 19, 2025
c6d272f
Added garbage collection
Jan 5, 2026
b5ac5b9
Cleaned up linting errors
Jan 6, 2026
b0fe865
just check passing
Jan 6, 2026
3cb63c5
Tidied comments
Jan 6, 2026
62cf9be
Merged in main from remote
Jan 6, 2026
a89c81b
Removed commented out code
Jan 6, 2026
11c517a
Apply suggestions to inline comments from code review
PabloAndresCQ Jan 13, 2026
e3d4609
fix: boost 1.90 dependecy conflict (#1353)
PabloAndresCQ Jan 12, 2026
ce8dd55
Gridsynth nit-picks and gate sequence normalisation (#1376)
PabloAndresCQ Jan 29, 2026
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
334 changes: 331 additions & 3 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,4 @@ cool_asserts = "2.0.4"
zstd = "0.13.3"
anyhow = "1.0.100"
num-rational = "0.4.2"

[profile.release.package.tket-py]
# Some configurations to reduce the size of tket wheels
strip = true
rsgridsynth = "0.2.0"
1 change: 0 additions & 1 deletion tket-py/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ tket = { path = "../tket", version = "0.16.0", features = [
] }
tket-qsystem = { path = "../tket-qsystem", version = "0.22.0" }
tket1-passes = { path = "../tket1-passes", version = "0.0.0" }

derive_more = { workspace = true, features = ["into", "from"] }
hugr = { workspace = true }
itertools = { workspace = true }
Expand Down
2 changes: 2 additions & 0 deletions tket-py/src/passes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Passes for optimising circuits.

pub mod chunks;
pub mod gridsynth;
pub mod tket1;

use std::{cmp::min, convert::TryInto, fs, num::NonZeroUsize, path::PathBuf};
Expand Down Expand Up @@ -29,6 +30,7 @@ pub fn module(py: Python<'_>) -> PyResult<Bound<'_, PyModule>> {
m.add_function(wrap_pyfunction!(normalize_guppy, &m)?)?;
m.add_class::<self::chunks::PyCircuitChunks>()?;
m.add_function(wrap_pyfunction!(self::chunks::chunks, &m)?)?;
m.add_function(wrap_pyfunction!(self::gridsynth::gridsynth, &m)?)?;
m.add_function(wrap_pyfunction!(self::tket1::tket1_pass, &m)?)?;
m.add("PullForwardError", py.get_type::<PyPullForwardError>())?;
m.add("TK1PassError", py.get_type::<tket1::PytketPassError>())?;
Expand Down
32 changes: 32 additions & 0 deletions tket-py/src/passes/gridsynth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! Bindings to allow users to access the gridsynth pass from Python.
//! The definitions here should be reflected in the
//! `tket-py/tket/_tket/passes.pyi` type stubs file
use crate::circuit::CircuitType;
use crate::circuit::try_with_circ;
use crate::utils::{ConvertPyErr, create_py_exception};
use pyo3::prelude::*;
use tket::passes::gridsynth::apply_gridsynth_pass;

create_py_exception!(
tket::passes::gridsynth::GridsynthError,
PyGridsynthError,
"Errors from the gridsynth pass."
);

/// Binding to a python function called gridsynth that runs the rust function called
/// apply_gridsynth pass behind the scenes
#[pyfunction]
pub fn gridsynth<'py>(
circ: &Bound<'py, PyAny>,
epsilon: f64,
simplify: bool,
) -> PyResult<Bound<'py, PyAny>> {
let py = circ.py();

try_with_circ(circ, |mut circ: tket::Circuit, typ: CircuitType| {
apply_gridsynth_pass(circ.hugr_mut(), epsilon, simplify).convert_pyerrs()?;

let circ = typ.convert(py, circ)?;
PyResult::Ok(circ)
})
}
12 changes: 12 additions & 0 deletions tket-py/tket/_tket/passes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,15 @@ def tket1_pass(
circuit-like regions, and optimise them too.
nested inside other subregions of the circuit.
"""

def gridsynth(hugr: CircuitClass, epsilon: float, simplify: bool) -> CircuitClass:
"""Runs a pass applying the gridsynth algorithm to all Rz gates in a HUGR,
which decomposes them into the Clifford + T basis.

Parameters:
- hugr: the hugr to run the pass on.
- epsilon: the precision of the gridsynth decomposition
- simplify: if `True`, each sequence of gridsynth gates is compressed into
a sequence of H*T and H*Tdg gates, sandwiched by Clifford gates. This sequence
always has a smaller number of S and H gates, and the same number of T+Tdg gates.
"""
46 changes: 46 additions & 0 deletions tket-py/tket/passes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
tket1_pass,
normalize_guppy,
PullForwardError,
gridsynth,
)

__all__ = [
Expand Down Expand Up @@ -176,3 +177,48 @@ def _normalize(self, hugr: Hugr, inplace: bool) -> PassResult:
)
new_hugr = Hugr.from_str(opt_program.to_str())
return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None)


@dataclass
class Gridsynth(ComposablePass):
epsilon: float
simplify: bool = True

"""Apply the gridsynth algorithm to all Rz gates in the Hugr.

This includes a NormalizeGuppy pass with all of the constituent passes applied
before applying gridsynth to standardise the
format.

Parameters:
- epsilon: The allowable error tolerance.
- simplify: If `True`, each sequence of gridsynth gates is compressed into
a sequence of H*T and H*Tdg gates, sandwiched by Clifford gates. This sequence
always has a smaller number of S and H gates, and the same number of T+Tdg gates.
"""

# TO DO: make the NormalizeGuppy pass optional, in case it is already run
# before Gridsynth. Need to warn users, at least in docs that if NormalizeGuppy
# is not run first then Gridsynth is likely to fail. Maybe issue the warning if
# the option to run NormalizeGuppy is set to False. The option would be specified
# as a field of the dataclass (would also need to add @dataclass decorator)
# like for NormalizeGuppy above
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine that NormalizeGuppy is always run at the start of the pass, as it is a pre-requesite. Is it a problem if NormalizeGuppy is run more than once? I expect it should leave the HUGR unchanged (I haven't checked).

def run(self, hugr: Hugr, *, inplace: bool = True) -> PassResult:
# inplace option does nothing for now but I retain for consistency of
# API with other passes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect we don't need to do anything special with inplace here, is it not enough to delegate to implement_pass_run as done below?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, implement_pass_run takes care of dealing with the missing case.

return implement_pass_run(
self,
hugr=hugr,
inplace=inplace,
copy_call=lambda h: self._apply_gridsynth_pass(
hugr, self.epsilon, self.simplify, inplace
),
)

def _apply_gridsynth_pass(
self, hugr: Hugr, epsilon: float, simplify: bool, inplace: bool
) -> PassResult:
compiler_state: Tk2Circuit = Tk2Circuit.from_bytes(hugr.to_bytes())
program = gridsynth(compiler_state, epsilon, simplify)
new_hugr = Hugr.from_str(program.to_str())
return PassResult.for_pass(self, hugr=new_hugr, inplace=inplace, result=None)
1 change: 1 addition & 0 deletions tket/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ pest_derive = { workspace = true }
zstd = { workspace = true, optional = true }
anyhow = { workspace = true, optional = true }
num-rational = { workspace = true }
rsgridsynth = { workspace = true }


[dev-dependencies]
Expand Down
2 changes: 2 additions & 0 deletions tket/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub use guppy::NormalizeGuppy;
pub mod pytket;
pub use pytket::lower_to_pytket;

pub mod gridsynth;

pub mod tuple_unpack;
#[expect(deprecated)]
pub use tuple_unpack::find_tuple_unpack_rewrites;
Expand Down
Loading
Loading