Skip to content
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
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ large_enum_variant = "allow"
[workspace.dependencies]

# Make sure to run `just recompile-eccs` if the hugr serialisation format changes.
hugr = "0.22.0"
hugr-core = "0.22.0"
hugr-cli = "0.22.0"
hugr = "0.22.1"
hugr-core = "0.22.1"
hugr-cli = "0.22.1"
portgraph = "0.15.1"
pyo3 = ">= 0.23.4, < 0.26"
itertools = "0.14.0"
Expand Down
12 changes: 11 additions & 1 deletion tket-qsystem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use hugr::{
hugr::{hugrmut::HugrMut, HugrError},
Hugr, HugrView, Node,
};
use lower_drops::LowerDropsPass;
use replace_bools::{ReplaceBoolPass, ReplaceBoolPassError};
use tket::TketOp;

Expand All @@ -29,7 +30,7 @@ pub mod cli;
pub mod extension;
#[cfg(feature = "llvm")]
pub mod llvm;

mod lower_drops;
pub mod replace_bools;

/// Modify a [hugr::Hugr] into a form that is acceptable for ingress into a
Expand Down Expand Up @@ -117,7 +118,12 @@ impl QSystemPass {
if self.lazify {
self.replace_bools().run(hugr)?;
}

// We expect any Hugr will have *either* drop ops, or ValueArrays (without drops),
// so only one of these passes will do anything; the order is thus immaterial.
self.lower_drops().run(hugr)?;
self.linearize_arrays().run(hugr)?;

#[cfg(feature = "llvm")]
{
// TODO: Remove "llvm" feature gate once `inline_constant_functions` is moved to
Expand Down Expand Up @@ -191,6 +197,10 @@ impl QSystemPass {
MonomorphizePass
}

fn lower_drops(&self) -> LowerDropsPass {
LowerDropsPass
}

fn linearize_arrays(&self) -> LinearizeArrayPass {
LinearizeArrayPass::default()
}
Expand Down
72 changes: 72 additions & 0 deletions tket-qsystem/src/lower_drops.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/// Contains a pass to lower "drop" ops from the Guppy extension
use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError, ReplacementOptions};
use hugr::algorithms::{ComposablePass, ReplaceTypes};
use hugr::builder::{Container, DFGBuilder};
use hugr::types::{Signature, Term};
use hugr::{hugr::hugrmut::HugrMut, Node};
use tket::extension::guppy::{DROP_OP_NAME, GUPPY_EXTENSION};

/// A pass that lowers "drop" ops from [GUPPY_EXTENSION]
#[derive(Default, Debug, Clone)]
pub struct LowerDropsPass;

impl<H: HugrMut<Node = Node>> ComposablePass<H> for LowerDropsPass {
type Error = ReplaceTypesError;

/// Returns whether any drops were lowered
type Result = bool;

fn run(&self, hugr: &mut H) -> Result<Self::Result, Self::Error> {
let mut rt = ReplaceTypes::default();
rt.replace_parametrized_op_with(
GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(),
|targs| {
let [Term::Runtime(ty)] = targs else {
panic!("Expected just one type")
};
// The Hugr here is invalid, so we have to pull it out manually
let mut dfb = DFGBuilder::new(Signature::new(ty.clone(), vec![])).unwrap();
let h = std::mem::take(dfb.hugr_mut());
Some(NodeTemplate::CompoundOp(Box::new(h)))
},
ReplacementOptions::default().with_linearization(true),
);
rt.run(hugr)
}
}

#[cfg(test)]
mod test {
use std::sync::Arc;

use hugr::builder::{inout_sig, Dataflow, DataflowHugr};
use hugr::ops::ExtensionOp;
use hugr::{extension::prelude::usize_t, std_extensions::collections::array::array_type};
use hugr::{Hugr, HugrView};

use super::*;

#[test]
fn test_lower_drop() {
let arr_type = array_type(2, usize_t());
let drop_op = GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap();
let drop_node = ExtensionOp::new(drop_op.clone(), [arr_type.clone().into()]).unwrap();
let mut b = DFGBuilder::new(inout_sig(arr_type, vec![])).unwrap();
let inp = b.input_wires();
b.add_dataflow_op(drop_node, inp).unwrap();
let mut h = b.finish_hugr_with_outputs([]).unwrap();
let count_drops = |h: &Hugr| {
h.nodes()
.filter(|n| {
h.get_optype(*n)
.as_extension_op()
.is_some_and(|e| Arc::ptr_eq(e.def_arc(), drop_op))
})
.count()
};
assert_eq!(count_drops(&h), 1);
LowerDropsPass.run(&mut h).unwrap();
h.validate().unwrap();
assert_eq!(count_drops(&h), 0);
}
}
Loading