Skip to content

Commit c9dda20

Browse files
authored
feat(pytket encoding): Support prelude barriers (#919)
1 parent 1bcacd6 commit c9dda20

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed

tket2/src/serialize/pytket/decoder/op.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ impl Tk1Op {
3636
num_qubits: usize,
3737
num_bits: usize,
3838
) -> Self {
39-
let op = if let Some(native) = NativeOp::try_from_serial_optype(serial_op.op_type.clone()) {
39+
let op = if let Some(native) =
40+
NativeOp::try_from_serial_optype(serial_op.op_type.clone(), num_qubits, num_bits)
41+
{
4042
Tk1Op::Native(native)
4143
} else {
4244
Tk1Op::Opaque(OpaqueTk1Op::new_from_op(serial_op, num_qubits, num_bits))

tket2/src/serialize/pytket/decoder/op/tk2op.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use hugr::std_extensions::arithmetic::float_types::float64_type;
99
use hugr::types::Signature;
1010

1111
use hugr::IncomingPort;
12+
use itertools::Itertools;
1213
use tket_json_rs::optype::OpType as Tk1OpType;
1314

1415
use crate::extension::rotation::rotation_type;
@@ -51,7 +52,11 @@ impl NativeOp {
5152
}
5253

5354
/// Returns the translated tket2 optype for this operation, if it exists.
54-
pub fn try_from_serial_optype(serial_op: Tk1OpType) -> Option<Self> {
55+
pub fn try_from_serial_optype(
56+
serial_op: Tk1OpType,
57+
num_qubits: usize,
58+
num_bits: usize,
59+
) -> Option<Self> {
5560
let op = match serial_op {
5661
Tk1OpType::H => Tk2Op::H.into(),
5762
Tk1OpType::CX => Tk2Op::CX.into(),
@@ -74,6 +79,12 @@ impl NativeOp {
7479
Tk1OpType::Reset => Tk2Op::Reset.into(),
7580
Tk1OpType::Measure => Tk2Op::Measure.into(),
7681
Tk1OpType::noop => Noop::new(qb_t()).into(),
82+
Tk1OpType::Barrier => {
83+
let qbs = std::iter::repeat_n(qb_t(), num_qubits);
84+
let bs = std::iter::repeat_n(bool_t(), num_bits);
85+
let types = qbs.chain(bs).collect_vec();
86+
hugr::extension::prelude::Barrier::new(types).into()
87+
}
7788
_ => {
7889
return None;
7990
}

tket2/src/serialize/pytket/extension/prelude.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ use super::PytketEmitter;
44
use crate::serialize::pytket::encoder::{EncodeStatus, RegisterCount, Tk1EncoderContext};
55
use crate::serialize::pytket::Tk1ConvertError;
66
use crate::Circuit;
7-
use hugr::extension::prelude::{TupleOpDef, PRELUDE_ID};
7+
use hugr::extension::prelude::{BarrierDef, TupleOpDef, PRELUDE_ID};
88
use hugr::extension::simple_op::MakeExtensionOp;
99
use hugr::extension::ExtensionId;
1010
use hugr::ops::ExtensionOp;
1111
use hugr::types::TypeArg;
1212
use hugr::HugrView;
13+
use tket_json_rs::optype::OpType as Tk1OpType;
1314

1415
/// Encoder for [prelude](hugr::extension::prelude) operations.
1516
#[derive(Debug, Clone, Default)]
@@ -30,6 +31,10 @@ impl<H: HugrView> PytketEmitter<H> for PreludeEmitter {
3031
if let Ok(tuple_op) = TupleOpDef::from_extension_op(op) {
3132
return self.tuple_op_to_pytket(node, op, &tuple_op, circ, encoder);
3233
};
34+
if let Ok(_barrier) = BarrierDef::from_extension_op(op) {
35+
encoder.emit_node(Tk1OpType::Barrier, node, circ)?;
36+
return Ok(EncodeStatus::Success);
37+
};
3338
Ok(EncodeStatus::Unsupported)
3439
}
3540

tket2/src/serialize/pytket/tests.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,20 @@ const PARAMETERIZED: &str = r#"{
7474
"implicit_permutation": [[["q", [0]], ["q", [0]]], [["q", [1]], ["q", [1]]]]
7575
}"#;
7676

77+
const BARRIER: &str = r#"{
78+
"phase": "0.0",
79+
"bits": [["c", [0]], ["c", [1]]],
80+
"qubits": [["q", [0]], ["q", [1]], ["q", [2]]],
81+
"commands": [
82+
{"args": [["q", [0]], ["q", [1]]], "op": {"type": "CX"}},
83+
{"args": [["q", [1]], ["q", [2]]], "op": {"type": "Barrier"}},
84+
{"args": [["q", [2]], ["c", [1]]], "op": {"type": "Measure"}}
85+
],
86+
"created_qubits": [],
87+
"discarded_qubits": [],
88+
"implicit_permutation": [[["q", [0]], ["q", [0]]], [["q", [1]], ["q", [1]]], [["q", [2]], ["q", [2]]]]
89+
}"#;
90+
7791
/// Check some properties of the serial circuit.
7892
fn validate_serial_circ(circ: &SerialCircuit) {
7993
// Check that all commands have valid arguments.
@@ -357,6 +371,7 @@ fn circ_complex_angle_computation() -> (Circuit, String) {
357371
#[case::simple(MULTI_REGISTER, 2, 3)]
358372
#[case::unknown_op(UNKNOWN_OP, 2, 3)]
359373
#[case::parametrized(PARAMETERIZED, 4, 2)]
374+
#[case::barrier(BARRIER, 3, 3)]
360375
fn json_roundtrip(#[case] circ_s: &str, #[case] num_commands: usize, #[case] num_qubits: usize) {
361376
let ser: circuit_json::SerialCircuit = serde_json::from_str(circ_s).unwrap();
362377
assert_eq!(ser.commands.len(), num_commands);

0 commit comments

Comments
 (0)