Skip to content

Commit

Permalink
Fixes for simulator qubit management (#303)
Browse files Browse the repository at this point in the history
This change includes two bugfixes:

- Evaluator now checks for qubit argument uniques on intrinsic gate
invocation to avoid triggering a panic in the simulator (treated instead
as a runtime error).
- Updates to a simulator package with the bug fix for dumping state
after a swap of two qubits where one has been released (see
qir-alliance/qir-runner#67)
  • Loading branch information
swernli authored May 12, 2023
1 parent d069216 commit c8afd68
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions compiler/qsc_eval/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ license.workspace = true
miette = { workspace = true }
num-bigint = { workspace = true }
num-complex = { workspace = true }
qir-backend = { git = "https://github.com/qir-alliance/qir-runner", rev = "617fa33e0966579c3ef5cf55ce20c7d2d76c09a7" }
qir-stdlib = { git = "https://github.com/qir-alliance/qir-runner", rev = "617fa33e0966579c3ef5cf55ce20c7d2d76c09a7" }
qir-backend = { git = "https://github.com/qir-alliance/qir-runner", rev = "7141d6ebc0a573dfe2871a362b46d98dfe6f751c" }
qir-stdlib = { git = "https://github.com/qir-alliance/qir-runner", rev = "7141d6ebc0a573dfe2871a362b46d98dfe6f751c" }
qsc_data_structures = { path = "../qsc_data_structures" }
qsc_hir = { path = "../qsc_hir" }
rand = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions compiler/qsc_eval/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ fn invoke_quantum_intrinsic(
$(stringify!($op2) => {
match args.try_into_tuple().with_span(args_span)?.as_ref() {
[x, y] => {
if x == y {
return Break(Reason::Error(Error::QubitUniqueness(args_span)));
}
$op2(
x.clone().try_into().with_span(args_span)?,
y.clone().try_into().with_span(args_span)?,
Expand All @@ -178,6 +181,9 @@ fn invoke_quantum_intrinsic(
$(stringify!($op3) => {
match args.try_into_tuple().with_span(args_span)?.as_ref() {
[x, y, z] => {
if x == y || y == z || x == z {
return Break(Reason::Error(Error::QubitUniqueness(args_span)));
}
$op3(
x.clone().try_into().with_span(args_span)?,
y.clone().try_into().with_span(args_span)?,
Expand Down
98 changes: 98 additions & 0 deletions compiler/qsc_eval/src/intrinsic/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,3 +882,101 @@ fn qubit_release_non_zero_failure() {
"#]],
);
}

#[test]
fn qubit_not_unique_two_qubit_error() {
check_intrinsic_output(
"",
indoc! {"{
use q = Qubit();
CNOT(q , q);
}"},
&expect![[r#"
QubitUniqueness(
Span {
lo: 32166,
hi: 32183,
},
)
"#]],
);
}

#[test]
fn qubit_not_unique_two_qubit_rotation_error() {
check_intrinsic_output(
"",
indoc! {"{
use q = Qubit();
Rxx(0.1, q, q);
}"},
&expect![[r#"
QubitUniqueness(
Span {
lo: 45069,
hi: 45092,
},
)
"#]],
);
}

#[test]
fn qubit_not_unique_three_qubit_error_first_second() {
check_intrinsic_output(
"",
indoc! {"{
use q = Qubit();
use a = Qubit();
CCNOT(q , q, a);
}"},
&expect![[r#"
QubitUniqueness(
Span {
lo: 31122,
hi: 31150,
},
)
"#]],
);
}

#[test]
fn qubit_not_unique_three_qubit_error_first_third() {
check_intrinsic_output(
"",
indoc! {"{
use q = Qubit();
use a = Qubit();
CCNOT(q , a, q);
}"},
&expect![[r#"
QubitUniqueness(
Span {
lo: 31122,
hi: 31150,
},
)
"#]],
);
}

#[test]
fn qubit_not_unique_three_qubit_error_second_third() {
check_intrinsic_output(
"",
indoc! {"{
use q = Qubit();
use a = Qubit();
CCNOT(a , q, q);
}"},
&expect![[r#"
QubitUniqueness(
Span {
lo: 31122,
hi: 31150,
},
)
"#]],
);
}
3 changes: 3 additions & 0 deletions compiler/qsc_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ pub enum Error {
#[error("output failure")]
Output(#[label("failed to generate output")] Span),

#[error("qubits in gate invocation are not unique")]
QubitUniqueness(#[label] Span),

#[error("range with step size of zero")]
RangeStepZero(#[label("invalid range")] Span),

Expand Down

0 comments on commit c8afd68

Please sign in to comment.