Skip to content

Commit c157a36

Browse files
authored
feat: Lower "Drop" op in guppy extension, update hugr minor version (#979)
Add LowerDropsPass, use in QSystemPass. hugr 0.22.0 -> 0.22.1 gets the "copy_discard_array" being in the default ReplaceTypes
1 parent 85ee480 commit c157a36

File tree

4 files changed

+98
-16
lines changed

4 files changed

+98
-16
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ large_enum_variant = "allow"
4747
[workspace.dependencies]
4848

4949
# Make sure to run `just recompile-eccs` if the hugr serialisation format changes.
50-
hugr = "0.22.0"
51-
hugr-core = "0.22.0"
52-
hugr-cli = "0.22.0"
50+
hugr = "0.22.1"
51+
hugr-core = "0.22.1"
52+
hugr-cli = "0.22.1"
5353
portgraph = "0.15.1"
5454
pyo3 = ">= 0.23.4, < 0.26"
5555
itertools = "0.14.0"

tket-qsystem/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use hugr::{
1313
hugr::{hugrmut::HugrMut, HugrError},
1414
Hugr, HugrView, Node,
1515
};
16+
use lower_drops::LowerDropsPass;
1617
use replace_bools::{ReplaceBoolPass, ReplaceBoolPassError};
1718
use tket::TketOp;
1819

@@ -29,7 +30,7 @@ pub mod cli;
2930
pub mod extension;
3031
#[cfg(feature = "llvm")]
3132
pub mod llvm;
32-
33+
mod lower_drops;
3334
pub mod replace_bools;
3435

3536
/// Modify a [hugr::Hugr] into a form that is acceptable for ingress into a
@@ -117,7 +118,12 @@ impl QSystemPass {
117118
if self.lazify {
118119
self.replace_bools().run(hugr)?;
119120
}
121+
122+
// We expect any Hugr will have *either* drop ops, or ValueArrays (without drops),
123+
// so only one of these passes will do anything; the order is thus immaterial.
124+
self.lower_drops().run(hugr)?;
120125
self.linearize_arrays().run(hugr)?;
126+
121127
#[cfg(feature = "llvm")]
122128
{
123129
// TODO: Remove "llvm" feature gate once `inline_constant_functions` is moved to
@@ -191,6 +197,10 @@ impl QSystemPass {
191197
MonomorphizePass
192198
}
193199

200+
fn lower_drops(&self) -> LowerDropsPass {
201+
LowerDropsPass
202+
}
203+
194204
fn linearize_arrays(&self) -> LinearizeArrayPass {
195205
LinearizeArrayPass::default()
196206
}

tket-qsystem/src/lower_drops.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/// Contains a pass to lower "drop" ops from the Guppy extension
2+
use hugr::algorithms::replace_types::{NodeTemplate, ReplaceTypesError, ReplacementOptions};
3+
use hugr::algorithms::{ComposablePass, ReplaceTypes};
4+
use hugr::builder::{Container, DFGBuilder};
5+
use hugr::types::{Signature, Term};
6+
use hugr::{hugr::hugrmut::HugrMut, Node};
7+
use tket::extension::guppy::{DROP_OP_NAME, GUPPY_EXTENSION};
8+
9+
/// A pass that lowers "drop" ops from [GUPPY_EXTENSION]
10+
#[derive(Default, Debug, Clone)]
11+
pub struct LowerDropsPass;
12+
13+
impl<H: HugrMut<Node = Node>> ComposablePass<H> for LowerDropsPass {
14+
type Error = ReplaceTypesError;
15+
16+
/// Returns whether any drops were lowered
17+
type Result = bool;
18+
19+
fn run(&self, hugr: &mut H) -> Result<Self::Result, Self::Error> {
20+
let mut rt = ReplaceTypes::default();
21+
rt.replace_parametrized_op_with(
22+
GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap(),
23+
|targs| {
24+
let [Term::Runtime(ty)] = targs else {
25+
panic!("Expected just one type")
26+
};
27+
// The Hugr here is invalid, so we have to pull it out manually
28+
let mut dfb = DFGBuilder::new(Signature::new(ty.clone(), vec![])).unwrap();
29+
let h = std::mem::take(dfb.hugr_mut());
30+
Some(NodeTemplate::CompoundOp(Box::new(h)))
31+
},
32+
ReplacementOptions::default().with_linearization(true),
33+
);
34+
rt.run(hugr)
35+
}
36+
}
37+
38+
#[cfg(test)]
39+
mod test {
40+
use std::sync::Arc;
41+
42+
use hugr::builder::{inout_sig, Dataflow, DataflowHugr};
43+
use hugr::ops::ExtensionOp;
44+
use hugr::{extension::prelude::usize_t, std_extensions::collections::array::array_type};
45+
use hugr::{Hugr, HugrView};
46+
47+
use super::*;
48+
49+
#[test]
50+
fn test_lower_drop() {
51+
let arr_type = array_type(2, usize_t());
52+
let drop_op = GUPPY_EXTENSION.get_op(DROP_OP_NAME.as_str()).unwrap();
53+
let drop_node = ExtensionOp::new(drop_op.clone(), [arr_type.clone().into()]).unwrap();
54+
let mut b = DFGBuilder::new(inout_sig(arr_type, vec![])).unwrap();
55+
let inp = b.input_wires();
56+
b.add_dataflow_op(drop_node, inp).unwrap();
57+
let mut h = b.finish_hugr_with_outputs([]).unwrap();
58+
let count_drops = |h: &Hugr| {
59+
h.nodes()
60+
.filter(|n| {
61+
h.get_optype(*n)
62+
.as_extension_op()
63+
.is_some_and(|e| Arc::ptr_eq(e.def_arc(), drop_op))
64+
})
65+
.count()
66+
};
67+
assert_eq!(count_drops(&h), 1);
68+
LowerDropsPass.run(&mut h).unwrap();
69+
h.validate().unwrap();
70+
assert_eq!(count_drops(&h), 0);
71+
}
72+
}

0 commit comments

Comments
 (0)