-
Notifications
You must be signed in to change notification settings - Fork 13
feat: gridsynth pass #1346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: gridsynth pass #1346
Changes from all commits
33276f6
0fa764e
df9ad08
c490e29
a02ab9b
946f6b8
e7430cd
689f24c
74ae91d
0c14b7d
c59dbc4
e2816cf
77c4e6d
e21532e
9072afa
ae18726
14fce82
9fef0b6
4060c73
9ae7961
ee01fea
350057b
d572aa4
ba45b19
7944c50
91ead38
a193513
45d5bc3
4844b87
ecea580
13a21b4
b8210fa
76e0059
2070eb5
31e2338
c3a04a6
59546a9
493f1d1
c78ad27
01a6c84
e5d5ba5
c6d272f
b5ac5b9
b0fe865
3cb63c5
62cf9be
a89c81b
11c517a
e3d4609
ce8dd55
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| 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) | ||
| }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,7 @@ | |
| tket1_pass, | ||
| normalize_guppy, | ||
| PullForwardError, | ||
| gridsynth, | ||
| ) | ||
|
|
||
| __all__ = [ | ||
|
|
@@ -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 | ||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I expect we don't need to do anything special with
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, |
||
| 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) | ||
There was a problem hiding this comment.
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).