diff --git a/tket2-py/src/passes.rs b/tket2-py/src/passes.rs index 87d19fc9..a747738a 100644 --- a/tket2-py/src/passes.rs +++ b/tket2-py/src/passes.rs @@ -6,8 +6,10 @@ use std::{cmp::min, convert::TryInto, fs, num::NonZeroUsize, path::PathBuf}; use pyo3::{prelude::*, types::IntoPyDict}; use tket2::optimiser::badger::BadgerOptions; -use tket2::{op_matches, passes::apply_greedy_commutation, Tk2Op}; +use tket2::passes; +use tket2::{op_matches, Tk2Op}; +use crate::circuit::CircuitType; use crate::utils::{create_py_exception, ConvertPyErr}; use crate::{ circuit::{try_update_circ, try_with_circ}, @@ -20,6 +22,7 @@ use crate::{ pub fn module(py: Python<'_>) -> PyResult> { let m = PyModule::new_bound(py, "passes")?; m.add_function(wrap_pyfunction!(greedy_depth_reduce, &m)?)?; + m.add_function(wrap_pyfunction!(lower_to_pytket, &m)?)?; m.add_function(wrap_pyfunction!(badger_optimise, &m)?)?; m.add_class::()?; m.add_function(wrap_pyfunction!(self::chunks::chunks, &m)?)?; @@ -46,7 +49,7 @@ create_py_exception!( fn greedy_depth_reduce<'py>(circ: &Bound<'py, PyAny>) -> PyResult<(Bound<'py, PyAny>, u32)> { let py = circ.py(); try_with_circ(circ, |mut circ, typ| { - let n_moves = apply_greedy_commutation(&mut circ).convert_pyerrs()?; + let n_moves = passes::apply_greedy_commutation(&mut circ).convert_pyerrs()?; let circ = typ.convert(py, circ)?; PyResult::Ok((circ, n_moves)) }) @@ -72,6 +75,24 @@ fn rebase_nam(circ: &Bound) -> PyResult<()> { rebase_pass.call1((circ,)).map(|_| ()) } +/// A pass that removes high-level control flow from a HUGR, so it can be used in pytket. +#[pyfunction] +fn lower_to_pytket<'py>(circ: &Bound<'py, PyAny>) -> PyResult> { + let py = circ.py(); + try_with_circ(circ, |circ, typ| match typ { + CircuitType::Tket1 => { + // If the circuit is already in tket1 format, just return it. + let circ = typ.convert(py, circ)?; + PyResult::Ok(circ) + } + CircuitType::Tket2 => { + let circ = passes::lower_to_pytket(&circ).convert_pyerrs()?; + let circ = typ.convert(py, circ)?; + PyResult::Ok(circ) + } + }) +} + /// Badger optimisation pass. /// /// HyperTKET's best attempt at optimising a circuit using circuit rewriting diff --git a/tket2-py/tket2/_tket2/passes.pyi b/tket2-py/tket2/_tket2/passes.pyi index 1e618e08..e0d19775 100644 --- a/tket2-py/tket2/_tket2/passes.pyi +++ b/tket2-py/tket2/_tket2/passes.pyi @@ -26,6 +26,9 @@ def greedy_depth_reduce(circ: CircuitClass) -> tuple[CircuitClass, int]: Returns the reduced circuit and the depth reduction. """ +def lower_to_pytket(circ: CircuitClass) -> CircuitClass: + """Lower the high-level operations in a Hugr so it can be interpreted by pytket.""" + def badger_optimise( circ: CircuitClass, optimiser: BadgerOptimiser, diff --git a/tket2-py/tket2/passes.py b/tket2-py/tket2/passes.py index ac545fa1..e63a5087 100644 --- a/tket2-py/tket2/passes.py +++ b/tket2-py/tket2/passes.py @@ -11,6 +11,7 @@ from ._tket2.passes import ( CircuitChunks, greedy_depth_reduce, + lower_to_pytket, badger_optimise, chunks, PullForwardError, @@ -22,6 +23,7 @@ # TODO: Wrap these in Python classes. "CircuitChunks", "greedy_depth_reduce", + "lower_to_pytket", "badger_optimise", "chunks", "PullForwardError",