Skip to content

Commit

Permalink
feat: add qalloc, qfree, reset ops (#284)
Browse files Browse the repository at this point in the history
Closes #283
  • Loading branch information
ss2165 authored Jan 16, 2024
1 parent 3587b8b commit 65eed46
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
7 changes: 6 additions & 1 deletion tket2/src/json/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ impl From<&JsonOp> for OpType {
JsonOpType::ZZMax => Tk2Op::ZZMax.into(),
JsonOpType::ZZPhase => Tk2Op::ZZPhase.into(),
JsonOpType::CZ => Tk2Op::CZ.into(),
JsonOpType::Reset => Tk2Op::Reset.into(),
JsonOpType::noop => LeafOp::Noop { ty: QB_T }.into(),
_ => LeafOp::CustomOp(Box::new(json_op.as_opaque_op())).into(),
}
Expand Down Expand Up @@ -228,12 +229,16 @@ impl TryFrom<&OpType> for JsonOp {
Tk2Op::RxF64 => JsonOpType::Rx,
// TODO: Use a TK2 opaque op once we update the tket-json-rs dependency.
Tk2Op::AngleAdd => {
unimplemented!("Serialising AngleAdd not supported. Are all constant folded?")
unimplemented!("Serialising AngleAdd not supported. Are all constants folded?")
}
Tk2Op::TK1 => JsonOpType::TK1,
Tk2Op::PhasedX => JsonOpType::PhasedX,
Tk2Op::ZZPhase => JsonOpType::ZZPhase,
Tk2Op::CZ => JsonOpType::CZ,
Tk2Op::Reset => JsonOpType::Reset,
Tk2Op::QAlloc | Tk2Op::QFree => {
unimplemented!("TKET1 does not support dynamic qubit allocation/discarding.")
}
}
} else if let LeafOp::CustomOp(b) = leaf {
let ext = (*b).as_ref();
Expand Down
34 changes: 32 additions & 2 deletions tket2/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ pub enum Tk2Op {
AngleAdd,
CZ,
TK1,
QAlloc,
QFree,
Reset,
}

/// Whether an op is a given Tk2Op.
Expand Down Expand Up @@ -99,7 +102,9 @@ impl MakeOpDef for Tk2Op {
let one_qb_row = type_row![QB_T];
let two_qb_row = type_row![QB_T, QB_T];
match self {
H | T | S | X | Y | Z | Tdg | Sdg => FunctionType::new(one_qb_row.clone(), one_qb_row),
H | T | S | X | Y | Z | Tdg | Sdg | Reset => {
FunctionType::new(one_qb_row.clone(), one_qb_row)
}
CX | ZZMax | CZ => FunctionType::new(two_qb_row.clone(), two_qb_row),
ZZPhase => FunctionType::new(type_row![QB_T, QB_T, FLOAT64_TYPE], two_qb_row),
Measure => FunctionType::new(one_qb_row, type_row![QB_T, BOOL_T]),
Expand All @@ -113,6 +118,8 @@ impl MakeOpDef for Tk2Op {
type_row![QB_T, FLOAT64_TYPE, FLOAT64_TYPE, FLOAT64_TYPE],
one_qb_row,
),
QAlloc => FunctionType::new(type_row![], one_qb_row),
QFree => FunctionType::new(one_qb_row, type_row![]),
}
.into()
}
Expand Down Expand Up @@ -159,7 +166,7 @@ impl Tk2Op {
match self {
H | CX | T | S | X | Y | Z | Tdg | Sdg | ZZMax | RzF64 | RxF64 | PhasedX | ZZPhase
| CZ | TK1 => true,
AngleAdd | Measure => false,
AngleAdd | Measure | QAlloc | QFree | Reset => false,
}
}
}
Expand Down Expand Up @@ -269,6 +276,7 @@ pub(crate) mod test {

use hugr::extension::simple_op::MakeOpDef;
use hugr::ops::OpName;
use hugr::CircuitUnit;
use hugr::{extension::OpDef, Hugr};
use rstest::{fixture, rstest};
use strum::IntoEnumIterator;
Expand Down Expand Up @@ -303,4 +311,26 @@ pub(crate) mod test {
fn check_t2_bell(t2_bell_circuit: Hugr) {
assert_eq!(t2_bell_circuit.commands().count(), 2);
}

#[test]
fn ancilla_circ() {
let h = build_simple_circuit(1, |circ| {
let empty: [CircuitUnit; 0] = []; // requires type annotation
let ancilla = circ.append_with_outputs(Tk2Op::QAlloc, empty)?[0];
let ancilla = circ.append_with_outputs(Tk2Op::Reset, [ancilla])?[0];

let ancilla = circ.append_with_outputs(
Tk2Op::CX,
[CircuitUnit::Linear(0), CircuitUnit::Wire(ancilla)],
)?[0];
let ancilla = circ.append_with_outputs(Tk2Op::Measure, [ancilla])?[0];
circ.append_and_consume(Tk2Op::QFree, [ancilla])?;

Ok(())
})
.unwrap();

// 5 commands: alloc, reset, cx, measure, free
assert_eq!(h.commands().count(), 5);
}
}

0 comments on commit 65eed46

Please sign in to comment.