Skip to content

Commit 58819ea

Browse files
committed
Add integration test in tket1-passes
1 parent eada88e commit 58819ea

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

Cargo.lock

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

tket1-passes/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ conan2 = "0.1.8"
2525

2626
[dev-dependencies]
2727
rstest.workspace = true
28+
itertools.workspace = true
29+
30+
# Used for testing
31+
hugr = { workspace = true }
32+
tket = { path = "../tket", version = "0.15.0" }
2833

2934
[lints]
3035
workspace = true
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//! Test running tket1 passes on hugr circuit.
2+
3+
use tket1_passes::Tket1Circuit;
4+
5+
use hugr::builder::{BuildError, Dataflow, DataflowHugr, FunctionBuilder};
6+
use hugr::extension::prelude::qb_t;
7+
use hugr::types::Signature;
8+
use hugr::{HugrView, Node};
9+
use rstest::{fixture, rstest};
10+
use tket::extension::{TKET1_EXTENSION_ID, TKET_EXTENSION_ID};
11+
use tket::serialize::pytket::{EncodeOptions, EncodedCircuit};
12+
use tket::{Circuit, TketOp};
13+
14+
/// A flat quantum circuit inside a function.
15+
///
16+
/// This should optimize to the identity.
17+
#[fixture]
18+
fn circ_flat_quantum() -> Circuit {
19+
fn build() -> Result<Circuit, BuildError> {
20+
let input_t = vec![qb_t(), qb_t()];
21+
let output_t = vec![qb_t(), qb_t()];
22+
let mut h =
23+
FunctionBuilder::new("preset_qubits", Signature::new(input_t, output_t)).unwrap();
24+
25+
let mut circ = h.as_circuit(h.input_wires());
26+
27+
circ.append(TketOp::X, [0])?;
28+
circ.append(TketOp::CX, [0, 1])?;
29+
circ.append(TketOp::X, [0])?;
30+
circ.append(TketOp::CX, [1, 0])?;
31+
circ.append(TketOp::X, [0])?;
32+
circ.append(TketOp::X, [1])?;
33+
circ.append(TketOp::CX, [0, 1])?;
34+
35+
let wires = circ.finish();
36+
// Implicit swap
37+
let wires = [wires[1], wires[0]];
38+
39+
let hugr = h.finish_hugr_with_outputs(wires).unwrap();
40+
41+
Ok(hugr.into())
42+
}
43+
build().unwrap()
44+
}
45+
46+
#[rstest]
47+
#[case(circ_flat_quantum(), 0)]
48+
fn test_clifford_simp(#[case] circ: Circuit, #[case] num_remaining_gates: usize) {
49+
let mut encoded = EncodedCircuit::new(&circ, EncodeOptions::new_with_subcircuits()).unwrap();
50+
51+
for (_region, serial_circuit) in encoded.iter_mut() {
52+
let mut circuit_ptr = Tket1Circuit::from_serial_circuit(serial_circuit).unwrap();
53+
circuit_ptr
54+
.clifford_simp(tket_json_rs::OpType::CX, true)
55+
.unwrap();
56+
*serial_circuit = circuit_ptr.to_serial_circuit().unwrap();
57+
}
58+
59+
let mut new_circ = circ.clone();
60+
let updated_regions = encoded
61+
.reassemble_inline(new_circ.hugr_mut(), None)
62+
.unwrap();
63+
64+
let quantum_ops: usize = updated_regions
65+
.iter()
66+
.map(|region| count_quantum_gates(&new_circ, *region))
67+
.sum();
68+
assert_eq!(quantum_ops, num_remaining_gates);
69+
}
70+
71+
/// Helper method to count the number of quantum operations in a hugr region.
72+
fn count_quantum_gates(circuit: &Circuit, region: Node) -> usize {
73+
circuit
74+
.hugr()
75+
.children(region)
76+
.filter(|child| {
77+
let op = circuit.hugr().get_optype(*child);
78+
op.as_extension_op()
79+
.is_some_and(|e| [TKET_EXTENSION_ID, TKET1_EXTENSION_ID].contains(e.extension_id()))
80+
})
81+
.count()
82+
}

0 commit comments

Comments
 (0)