From 68c22b436dabe51f81ad10873465a147378dcccd Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 12 Nov 2025 15:45:43 +0000 Subject: [PATCH 1/8] QSystem guppy_opt.rs tests call out to tket1-passes --- Cargo.lock | 2 ++ tket-qsystem/Cargo.toml | 2 ++ tket-qsystem/tests/guppy_opt.rs | 51 +++++++++++++++++++++++++++++---- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9a2311a7c..df4cc4dce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2727,6 +2727,7 @@ dependencies = [ "itertools 0.14.0", "lazy_static", "petgraph 0.8.3", + "rayon", "rstest", "serde", "serde_json", @@ -2734,6 +2735,7 @@ dependencies = [ "strum", "tket", "tket-json-rs", + "tket1-passes", "typetag", ] diff --git a/tket-qsystem/Cargo.toml b/tket-qsystem/Cargo.toml index 310993d2f..83af7de74 100644 --- a/tket-qsystem/Cargo.toml +++ b/tket-qsystem/Cargo.toml @@ -49,6 +49,8 @@ cool_asserts.workspace = true petgraph.workspace = true rstest.workspace = true serde_json.workspace = true +tket1-passes = { path = "../tket1-passes" } +rayon.workspace = true [lints] workspace = true diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 5ee016a57..b022399c4 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -2,6 +2,7 @@ use smol_str::SmolStr; use std::collections::HashMap; +use rayon::iter::ParallelIterator; use std::fs; use std::io::BufReader; use std::path::Path; @@ -11,6 +12,10 @@ use hugr::algorithms::ComposablePass; use hugr::{Hugr, HugrView}; use rstest::{fixture, rstest}; use tket::passes::NormalizeGuppy; +use tket::serialize::pytket::{EncodeOptions, EncodedCircuit}; +use tket::Circuit; + +use tket1_passes::Tket1Circuit; use tket_qsystem::QSystemPass; const GUPPY_EXAMPLES_DIR: &str = "../test_files/guppy_optimization"; @@ -47,6 +52,24 @@ fn guppy_simple_cx() -> Hugr { load_guppy_circuit("simple_cx") } +fn run_pytket(h: &mut Hugr) { + let circ = Circuit::new(h); + let mut encoded = + EncodedCircuit::new(&circ, EncodeOptions::new().with_subcircuits(true)).unwrap(); + + encoded + .par_iter_mut() + .for_each(|(_region, serial_circuit)| { + let mut circuit_ptr = Tket1Circuit::from_serial_circuit(serial_circuit).unwrap(); + circuit_ptr + .clifford_simp(tket_json_rs::OpType::CX, true) + .unwrap(); + *serial_circuit = circuit_ptr.to_serial_circuit().unwrap(); + }); + + encoded.reassemble_inplace(circ.into_hugr(), None).unwrap(); +} + fn count_gates(h: &impl HugrView) -> HashMap { let mut counts = HashMap::new(); for n in h.nodes() { @@ -67,28 +90,46 @@ fn count_gates(h: &impl HugrView) -> HashMap { #[case::angles(guppy_angles(), [ ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.Rz", 2), ("tket.quantum.MeasureFree", 1) ])] -#[case::false_branch(guppy_false_branch(), [ - ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.MeasureFree", 1) -])] #[case::nested(guppy_nested(), [ ("tket.quantum.CZ", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 3), ("tket.quantum.MeasureFree", 3) ])] #[case::ranges(guppy_ranges(), [ ("tket.quantum.QAlloc", 4), ("tket.quantum.MeasureFree", 4), ("tket.quantum.H", 2), ("tket.quantum.CX", 2) ])] +#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri +fn no_optimise_guppy<'a>( + #[case] hugr: Hugr, + #[case] before_after: impl IntoIterator + Clone, +) { + optimise_guppy(hugr, before_after.clone(), before_after); +} + +#[rstest] +#[case::false_branch(guppy_false_branch(), [ + ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.MeasureFree", 1) +], [ + ("TKET1.tk1op", 1), ("tket.quantum.QAlloc", 1), ("tket.quantum.H", 1), ("tket.quantum.MeasureFree", 1) +])] #[case::simple_cx(guppy_simple_cx(), [ ("tket.quantum.QAlloc", 2), ("tket.quantum.CX", 2), ("tket.quantum.MeasureFree", 2) +], [ + ("tket.quantum.MeasureFree", 2), ("tket.quantum.QAlloc", 2) ])] -#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri fn optimise_guppy<'a>( #[case] mut hugr: Hugr, #[case] before: impl IntoIterator, + #[case] after: impl IntoIterator, ) { NormalizeGuppy::default().run(&mut hugr).unwrap(); let before = before.into_iter().map(|(k, v)| (k.into(), v)).collect(); assert_eq!(count_gates(&hugr), before); - // TODO: Run pytket passes here, and check that the circuit is as optimized as possible at this point. + run_pytket(&mut hugr); + + let after = after.into_iter().map(|(k, v)| (k.into(), v)).collect(); + assert_eq!(count_gates(&hugr), after); + + // TODO: check that the circuit is as optimized as possible at this point. // // Most example circuits optimize to identity functions, so it may be possible to check for that. From b9b004b6eabf9d30abd0fb8b89fd48bd34327d91 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 12 Nov 2025 17:56:09 +0000 Subject: [PATCH 2/8] more/explicit tests --- tket-qsystem/tests/guppy_opt.rs | 85 ++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index b022399c4..b495f58b3 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -1,8 +1,8 @@ //! Tests optimizing Guppy-generated programs. +use rayon::iter::ParallelIterator; use smol_str::SmolStr; use std::collections::HashMap; -use rayon::iter::ParallelIterator; use std::fs; use std::io::BufReader; use std::path::Path; @@ -20,36 +20,36 @@ use tket_qsystem::QSystemPass; const GUPPY_EXAMPLES_DIR: &str = "../test_files/guppy_optimization"; -fn load_guppy_circuit(name: &str) -> Hugr { - let file = Path::new(GUPPY_EXAMPLES_DIR).join(format!("{name}/{name}.hugr")); - let reader = fs::File::open(file).unwrap(); +fn load_guppy_circuit(path: &str) -> std::io::Result { + let file = Path::new(GUPPY_EXAMPLES_DIR).join(format!("{path}.hugr")); + let reader = fs::File::open(file)?; let reader = BufReader::new(reader); - Hugr::load(reader, None).unwrap() + Ok(Hugr::load(reader, None).unwrap()) } #[fixture] fn guppy_angles() -> Hugr { - load_guppy_circuit("angles") + load_guppy_circuit("angles/angles").unwrap() } #[fixture] fn guppy_false_branch() -> Hugr { - load_guppy_circuit("false_branch") + load_guppy_circuit("false_branch/false_branch").unwrap() } #[fixture] fn guppy_nested() -> Hugr { - load_guppy_circuit("nested") + load_guppy_circuit("nested/nested").unwrap() } #[fixture] fn guppy_ranges() -> Hugr { - load_guppy_circuit("ranges") + load_guppy_circuit("ranges/ranges").unwrap() } #[fixture] fn guppy_simple_cx() -> Hugr { - load_guppy_circuit("simple_cx") + load_guppy_circuit("simple_cx/simple_cx").unwrap() } fn run_pytket(h: &mut Hugr) { @@ -86,23 +86,6 @@ fn count_gates(h: &impl HugrView) -> HashMap { /// /// This test is intended to check the current status of the Guppy optimization passes. /// -#[rstest] -#[case::angles(guppy_angles(), [ - ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.Rz", 2), ("tket.quantum.MeasureFree", 1) -])] -#[case::nested(guppy_nested(), [ - ("tket.quantum.CZ", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 3), ("tket.quantum.MeasureFree", 3) -])] -#[case::ranges(guppy_ranges(), [ - ("tket.quantum.QAlloc", 4), ("tket.quantum.MeasureFree", 4), ("tket.quantum.H", 2), ("tket.quantum.CX", 2) -])] -#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri -fn no_optimise_guppy<'a>( - #[case] hugr: Hugr, - #[case] before_after: impl IntoIterator + Clone, -) { - optimise_guppy(hugr, before_after.clone(), before_after); -} #[rstest] #[case::false_branch(guppy_false_branch(), [ @@ -115,10 +98,11 @@ fn no_optimise_guppy<'a>( ], [ ("tket.quantum.MeasureFree", 2), ("tket.quantum.QAlloc", 2) ])] -fn optimise_guppy<'a>( +#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri +fn optimise_guppy( #[case] mut hugr: Hugr, - #[case] before: impl IntoIterator, - #[case] after: impl IntoIterator, + #[case] before: impl IntoIterator, usize)>, + #[case] after: impl IntoIterator, usize)>, ) { NormalizeGuppy::default().run(&mut hugr).unwrap(); let before = before.into_iter().map(|(k, v)| (k.into(), v)).collect(); @@ -129,12 +113,45 @@ fn optimise_guppy<'a>( let after = after.into_iter().map(|(k, v)| (k.into(), v)).collect(); assert_eq!(count_gates(&hugr), after); - // TODO: check that the circuit is as optimized as possible at this point. - // - // Most example circuits optimize to identity functions, so it may be possible to check for that. - // Lower to QSystem. This may blow up the HUGR size. QSystemPass::default().run(&mut hugr).unwrap(); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } + +/// Checks that pytket does nothing for these examples. +/// We include gate counts for after the NormalizeGuppy step +/// as our flattening is not sufficient to match the .flat.hugr +#[rstest] +#[case::angles(guppy_angles(), [ + ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.Rz", 2), ("tket.quantum.MeasureFree", 1) +])] +#[case::nested(guppy_nested(), [ + ("tket.quantum.CZ", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 3), ("tket.quantum.MeasureFree", 3) +])] +#[case::ranges(guppy_ranges(), [ + ("tket.quantum.QAlloc", 4), ("tket.quantum.MeasureFree", 4), ("tket.quantum.H", 2), ("tket.quantum.CX", 2) +])] +#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri +fn no_optimise_guppy<'a>( + #[case] hugr: Hugr, + #[case] before_after: impl IntoIterator + Clone, +) { + optimise_guppy(hugr, before_after.clone(), before_after); +} + +/// Check that each example optimizes to the full extent given by the .opt (and .flat) .hugr files. +#[should_panic] /// This does not yet pass for any case! +#[rstest] +#[case::angles("angles")] +#[case::false_branch("false_branch")] +#[case::simple_cx("simple_cx")] +#[case::nested("nested")] +#[case::ranges("ranges")] +fn optimise_guppy_full(#[case] name: &str) { + let hugr = load_guppy_circuit(&format!("{name}/{name}")).unwrap(); + let flat = load_guppy_circuit(&format!("{name}/{name}.flat")).unwrap_or(hugr.clone()); + let opt = load_guppy_circuit(&format!("{name}/{name}.opt")).unwrap(); + + optimise_guppy(hugr, count_gates(&flat), count_gates(&opt)) +} From a3902c6c44a8e6f3821220ef7d9cc02a5c19914e Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 12 Nov 2025 18:29:40 +0000 Subject: [PATCH 3/8] fmt differently --- tket-qsystem/tests/guppy_opt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index b495f58b3..351a456c9 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -141,7 +141,7 @@ fn no_optimise_guppy<'a>( } /// Check that each example optimizes to the full extent given by the .opt (and .flat) .hugr files. -#[should_panic] /// This does not yet pass for any case! +#[should_panic] // This does not yet pass for any case! #[rstest] #[case::angles("angles")] #[case::false_branch("false_branch")] From 1dfadbb640e2c7fee7071839d8adce2022f36531 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 12 Nov 2025 18:38:57 +0000 Subject: [PATCH 4/8] move should_panic --- tket-qsystem/tests/guppy_opt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 351a456c9..1142f92bc 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -141,13 +141,13 @@ fn no_optimise_guppy<'a>( } /// Check that each example optimizes to the full extent given by the .opt (and .flat) .hugr files. -#[should_panic] // This does not yet pass for any case! #[rstest] #[case::angles("angles")] #[case::false_branch("false_branch")] #[case::simple_cx("simple_cx")] #[case::nested("nested")] #[case::ranges("ranges")] +#[should_panic] // This does not yet pass for any case! fn optimise_guppy_full(#[case] name: &str) { let hugr = load_guppy_circuit(&format!("{name}/{name}")).unwrap(); let flat = load_guppy_circuit(&format!("{name}/{name}.flat")).unwrap_or(hugr.clone()); From c0cca1145708e6fec1d5fd29e709e4bde45f5a23 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 14 Nov 2025 17:07:07 +0000 Subject: [PATCH 5/8] Switched to enum HugrFileType {Original, Flat, Optimized} --- tket-qsystem/tests/guppy_opt.rs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 1142f92bc..9c223718f 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -20,8 +20,19 @@ use tket_qsystem::QSystemPass; const GUPPY_EXAMPLES_DIR: &str = "../test_files/guppy_optimization"; -fn load_guppy_circuit(path: &str) -> std::io::Result { - let file = Path::new(GUPPY_EXAMPLES_DIR).join(format!("{path}.hugr")); +enum HugrFileType { + Original, + Flat, + Optimized, +} + +fn load_guppy_circuit(name: &str, file_type: HugrFileType) -> std::io::Result { + let suffix = match file_type { + HugrFileType::Original => "", + HugrFileType::Flat => ".flat", + HugrFileType::Optimized => ".opt", + }; + let file = Path::new(GUPPY_EXAMPLES_DIR).join(format!("{name}/{name}{suffix}.hugr")); let reader = fs::File::open(file)?; let reader = BufReader::new(reader); Ok(Hugr::load(reader, None).unwrap()) @@ -29,27 +40,27 @@ fn load_guppy_circuit(path: &str) -> std::io::Result { #[fixture] fn guppy_angles() -> Hugr { - load_guppy_circuit("angles/angles").unwrap() + load_guppy_circuit("angles", HugrFileType::Original).unwrap() } #[fixture] fn guppy_false_branch() -> Hugr { - load_guppy_circuit("false_branch/false_branch").unwrap() + load_guppy_circuit("false_branch", HugrFileType::Original).unwrap() } #[fixture] fn guppy_nested() -> Hugr { - load_guppy_circuit("nested/nested").unwrap() + load_guppy_circuit("nested", HugrFileType::Original).unwrap() } #[fixture] fn guppy_ranges() -> Hugr { - load_guppy_circuit("ranges/ranges").unwrap() + load_guppy_circuit("ranges", HugrFileType::Original).unwrap() } #[fixture] fn guppy_simple_cx() -> Hugr { - load_guppy_circuit("simple_cx/simple_cx").unwrap() + load_guppy_circuit("simple_cx", HugrFileType::Original).unwrap() } fn run_pytket(h: &mut Hugr) { @@ -149,9 +160,9 @@ fn no_optimise_guppy<'a>( #[case::ranges("ranges")] #[should_panic] // This does not yet pass for any case! fn optimise_guppy_full(#[case] name: &str) { - let hugr = load_guppy_circuit(&format!("{name}/{name}")).unwrap(); - let flat = load_guppy_circuit(&format!("{name}/{name}.flat")).unwrap_or(hugr.clone()); - let opt = load_guppy_circuit(&format!("{name}/{name}.opt")).unwrap(); + let hugr = load_guppy_circuit(name, HugrFileType::Original).unwrap(); + let flat = load_guppy_circuit(name, HugrFileType::Flat).unwrap_or(hugr.clone()); + let opt = load_guppy_circuit(name, HugrFileType::Optimized).unwrap(); optimise_guppy(hugr, count_gates(&flat), count_gates(&opt)) } From bc57a698b9bb4a3059f7fdd0031782fdb2afbe5d Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 14 Nov 2025 17:42:27 +0000 Subject: [PATCH 6/8] Add separate optimize_guppy_pytket / flatten_guppy steps --- tket-qsystem/tests/guppy_opt.rs | 51 +++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 9c223718f..5d0b1b063 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -98,6 +98,57 @@ fn count_gates(h: &impl HugrView) -> HashMap { /// This test is intended to check the current status of the Guppy optimization passes. /// +#[rstest] +#[should_panic = "xfail"] +#[case::angles("angles", Some(vec![ + ("tket.quantum.Rz", 2), ("tket.quantum.MeasureFree", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1) +]))] +#[should_panic = "xfail"] +#[case::simple_cx("simple_cx", Some(vec![ + ("tket.quantum.QAlloc", 2), ("tket.quantum.MeasureFree", 2), +]))] +#[should_panic = "xfail"] +#[case::nested("nested", Some(vec![ + ("tket.quantum.CZ", 6), ("tket.quantum.QAlloc", 3), ("tket.quantum.MeasureFree", 3), ("tket.quantum.H", 6) +]))] +#[should_panic = "xfail"] +#[case::ranges("ranges", Some(vec![ + ("tket.quantum.H", 8), ("tket.quantum.MeasureFree", 4), ("tket.quantum.QAlloc", 4), ("tket.quantum.CX", 6) +]))] +#[should_panic = "xfail"] +#[case::false_branch("false_branch", Some(vec![ + ("TKET1.tk1op", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.MeasureFree", 1) +]))] +#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri +fn optimise_guppy_pytket(#[case] name: &str, #[case] xfail: Option>) { + let mut hugr = load_guppy_circuit(name, HugrFileType::Flat) + .unwrap_or_else(|_| load_guppy_circuit(name, HugrFileType::Original).unwrap()); + run_pytket(&mut hugr); + let should_xfail = xfail.is_some(); + let expected_counts = match xfail { + Some(counts) => counts.into_iter().map(|(k, v)| (k.into(), v)).collect(), + None => count_gates(&load_guppy_circuit(name, HugrFileType::Optimized).unwrap()), + }; + assert_eq!(count_gates(&hugr), expected_counts); + if should_xfail { + panic!("xfail"); + } +} + +#[rstest] +#[case::angles("angles")] +#[should_panic] +#[case::nested("nested")] +#[should_panic] +#[case::ranges("ranges")] +#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri +fn flatten_guppy(#[case] name: &str) { + let mut hugr = load_guppy_circuit(name, HugrFileType::Original).unwrap(); + NormalizeGuppy::default().run(&mut hugr).unwrap(); + let target = load_guppy_circuit(name, HugrFileType::Flat).unwrap(); + assert_eq!(count_gates(&hugr), count_gates(&target)); +} + #[rstest] #[case::false_branch(guppy_false_branch(), [ ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.MeasureFree", 1) From 50bdfe29714464b1b45934eae66010f76ca7e16b Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 14 Nov 2025 17:47:23 +0000 Subject: [PATCH 7/8] Drop some other tests, keep optimise_guppy(_full=>) --- tket-qsystem/tests/guppy_opt.rs | 76 +++++++++------------------------ 1 file changed, 19 insertions(+), 57 deletions(-) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 5d0b1b063..4a5f6a0f1 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -149,71 +149,33 @@ fn flatten_guppy(#[case] name: &str) { assert_eq!(count_gates(&hugr), count_gates(&target)); } +/// Check that each example optimizes to the full extent given by the .opt (and .flat) .hugr files. #[rstest] -#[case::false_branch(guppy_false_branch(), [ - ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.MeasureFree", 1) -], [ - ("TKET1.tk1op", 1), ("tket.quantum.QAlloc", 1), ("tket.quantum.H", 1), ("tket.quantum.MeasureFree", 1) -])] -#[case::simple_cx(guppy_simple_cx(), [ - ("tket.quantum.QAlloc", 2), ("tket.quantum.CX", 2), ("tket.quantum.MeasureFree", 2) -], [ - ("tket.quantum.MeasureFree", 2), ("tket.quantum.QAlloc", 2) -])] -#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri -fn optimise_guppy( - #[case] mut hugr: Hugr, - #[case] before: impl IntoIterator, usize)>, - #[case] after: impl IntoIterator, usize)>, -) { +#[case::angles("angles")] +#[case::false_branch("false_branch")] +#[case::simple_cx("simple_cx")] +#[case::nested("nested")] +#[case::ranges("ranges")] +#[should_panic] // This does not yet pass for any case! +fn optimise_guppy(#[case] name: &str) { + let mut hugr = load_guppy_circuit(name, HugrFileType::Original).unwrap(); + let flat = count_gates( + load_guppy_circuit(name, HugrFileType::Flat) + .ok() + .as_ref() + .unwrap_or(&hugr), + ); + let opt = count_gates(&load_guppy_circuit(name, HugrFileType::Optimized).unwrap()); + NormalizeGuppy::default().run(&mut hugr).unwrap(); - let before = before.into_iter().map(|(k, v)| (k.into(), v)).collect(); - assert_eq!(count_gates(&hugr), before); + assert_eq!(count_gates(&hugr), flat); run_pytket(&mut hugr); - let after = after.into_iter().map(|(k, v)| (k.into(), v)).collect(); - assert_eq!(count_gates(&hugr), after); + assert_eq!(count_gates(&hugr), opt); // Lower to QSystem. This may blow up the HUGR size. QSystemPass::default().run(&mut hugr).unwrap(); hugr.validate().unwrap_or_else(|e| panic!("{e}")); } - -/// Checks that pytket does nothing for these examples. -/// We include gate counts for after the NormalizeGuppy step -/// as our flattening is not sufficient to match the .flat.hugr -#[rstest] -#[case::angles(guppy_angles(), [ - ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 1), ("tket.quantum.Rz", 2), ("tket.quantum.MeasureFree", 1) -])] -#[case::nested(guppy_nested(), [ - ("tket.quantum.CZ", 1), ("tket.quantum.H", 2), ("tket.quantum.QAlloc", 3), ("tket.quantum.MeasureFree", 3) -])] -#[case::ranges(guppy_ranges(), [ - ("tket.quantum.QAlloc", 4), ("tket.quantum.MeasureFree", 4), ("tket.quantum.H", 2), ("tket.quantum.CX", 2) -])] -#[cfg_attr(miri, ignore)] // Opening files is not supported in (isolated) miri -fn no_optimise_guppy<'a>( - #[case] hugr: Hugr, - #[case] before_after: impl IntoIterator + Clone, -) { - optimise_guppy(hugr, before_after.clone(), before_after); -} - -/// Check that each example optimizes to the full extent given by the .opt (and .flat) .hugr files. -#[rstest] -#[case::angles("angles")] -#[case::false_branch("false_branch")] -#[case::simple_cx("simple_cx")] -#[case::nested("nested")] -#[case::ranges("ranges")] -#[should_panic] // This does not yet pass for any case! -fn optimise_guppy_full(#[case] name: &str) { - let hugr = load_guppy_circuit(name, HugrFileType::Original).unwrap(); - let flat = load_guppy_circuit(name, HugrFileType::Flat).unwrap_or(hugr.clone()); - let opt = load_guppy_circuit(name, HugrFileType::Optimized).unwrap(); - - optimise_guppy(hugr, count_gates(&flat), count_gates(&opt)) -} From 0ebc1b74509fd73f8f01acf8455df3ce432d3e01 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 14 Nov 2025 17:51:54 +0000 Subject: [PATCH 8/8] remove unused fixtures --- tket-qsystem/tests/guppy_opt.rs | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/tket-qsystem/tests/guppy_opt.rs b/tket-qsystem/tests/guppy_opt.rs index 4a5f6a0f1..7a5352764 100644 --- a/tket-qsystem/tests/guppy_opt.rs +++ b/tket-qsystem/tests/guppy_opt.rs @@ -10,7 +10,7 @@ use tket::extension::{TKET1_EXTENSION_ID, TKET_EXTENSION_ID}; use hugr::algorithms::ComposablePass; use hugr::{Hugr, HugrView}; -use rstest::{fixture, rstest}; +use rstest::rstest; use tket::passes::NormalizeGuppy; use tket::serialize::pytket::{EncodeOptions, EncodedCircuit}; use tket::Circuit; @@ -38,31 +38,6 @@ fn load_guppy_circuit(name: &str, file_type: HugrFileType) -> std::io::Result Hugr { - load_guppy_circuit("angles", HugrFileType::Original).unwrap() -} - -#[fixture] -fn guppy_false_branch() -> Hugr { - load_guppy_circuit("false_branch", HugrFileType::Original).unwrap() -} - -#[fixture] -fn guppy_nested() -> Hugr { - load_guppy_circuit("nested", HugrFileType::Original).unwrap() -} - -#[fixture] -fn guppy_ranges() -> Hugr { - load_guppy_circuit("ranges", HugrFileType::Original).unwrap() -} - -#[fixture] -fn guppy_simple_cx() -> Hugr { - load_guppy_circuit("simple_cx", HugrFileType::Original).unwrap() -} - fn run_pytket(h: &mut Hugr) { let circ = Circuit::new(h); let mut encoded =