From 21027a429a98787126c6bf4556d5e4b2f1c9d851 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Thu, 12 Dec 2024 13:09:32 +0000 Subject: [PATCH 1/3] feat: add measure_array quantum function --- guppylang/std/quantum.py | 12 +++++++++++- tests/integration/test_quantum.py | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/guppylang/std/quantum.py b/guppylang/std/quantum.py index d937da61..1ef14ae2 100644 --- a/guppylang/std/quantum.py +++ b/guppylang/std/quantum.py @@ -13,7 +13,7 @@ ) from guppylang.std._internal.util import quantum_op from guppylang.std.angles import angle -from guppylang.std.builtins import owned +from guppylang.std.builtins import array, owned from guppylang.std.option import Option @@ -144,3 +144,13 @@ def measure(q: qubit @ owned) -> bool: ... @guppy.hugr_op(quantum_op("Reset")) @no_type_check def reset(q: qubit) -> None: ... + + +N = guppy.nat_var("N") + + +@guppy +@no_type_check +def measure_array(qubits: array[qubit, N] @ owned) -> array[bool, N]: + """Measure an array of qubits, returning an array of bools.""" + return array(measure(q) for q in qubits) diff --git a/tests/integration/test_quantum.py b/tests/integration/test_quantum.py index b94efef0..2bd18e45 100644 --- a/tests/integration/test_quantum.py +++ b/tests/integration/test_quantum.py @@ -6,9 +6,9 @@ from guppylang.module import GuppyModule from guppylang.std.angles import angle -from guppylang.std.builtins import owned +from guppylang.std.builtins import owned, array -from guppylang.std.quantum import discard, measure, qubit, maybe_qubit +from guppylang.std.quantum import discard, measure, qubit, maybe_qubit, measure_array from guppylang.std.quantum_functional import ( cx, cy, @@ -43,7 +43,7 @@ def compile_quantum_guppy(fn) -> ModulePointer: ), "`@compile_quantum_guppy` does not support extra arguments." module = GuppyModule("module") - module.load(angle, qubit, discard, measure, maybe_qubit) + module.load(angle, qubit, discard, measure, measure_array, maybe_qubit) module.load_all(quantum_functional) guppylang.decorator.guppy(module)(fn) return module.compile() @@ -123,3 +123,15 @@ def test( q2 = rz(q2, a3) q1, q2 = crz(q1, q2, a3) return (q1, q2) + + +def test_measure_array(validate): + """Build and measure array.""" + + @compile_quantum_guppy + def test() -> array[bool, 10]: + qs = array(qubit() for _ in range(10)) + return measure_array(qs) + validate(test) + + From e7e1be9817137e1c8097b75cfa9210c27b99b795 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Thu, 12 Dec 2024 13:19:02 +0000 Subject: [PATCH 2/3] feat: add discard_array --- guppylang/std/quantum.py | 6 ++++++ tests/integration/test_quantum.py | 23 +++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/guppylang/std/quantum.py b/guppylang/std/quantum.py index 1ef14ae2..2e0bac48 100644 --- a/guppylang/std/quantum.py +++ b/guppylang/std/quantum.py @@ -154,3 +154,9 @@ def reset(q: qubit) -> None: ... def measure_array(qubits: array[qubit, N] @ owned) -> array[bool, N]: """Measure an array of qubits, returning an array of bools.""" return array(measure(q) for q in qubits) + +@guppy +@no_type_check +def discard_array(qubits: array[qubit, N] @ owned) -> None: + """Discard an array of qubits.""" + _ = array(discard(q) for q in qubits) diff --git a/tests/integration/test_quantum.py b/tests/integration/test_quantum.py index 2bd18e45..17e77ace 100644 --- a/tests/integration/test_quantum.py +++ b/tests/integration/test_quantum.py @@ -8,7 +8,14 @@ from guppylang.std.builtins import owned, array -from guppylang.std.quantum import discard, measure, qubit, maybe_qubit, measure_array +from guppylang.std.quantum import ( + discard, + measure, + qubit, + maybe_qubit, + measure_array, + discard_array, +) from guppylang.std.quantum_functional import ( cx, cy, @@ -43,7 +50,9 @@ def compile_quantum_guppy(fn) -> ModulePointer: ), "`@compile_quantum_guppy` does not support extra arguments." module = GuppyModule("module") - module.load(angle, qubit, discard, measure, measure_array, maybe_qubit) + module.load( + angle, qubit, discard, measure, measure_array, maybe_qubit, discard_array + ) module.load_all(quantum_functional) guppylang.decorator.guppy(module)(fn) return module.compile() @@ -132,6 +141,16 @@ def test_measure_array(validate): def test() -> array[bool, 10]: qs = array(qubit() for _ in range(10)) return measure_array(qs) + validate(test) +def test_discard_array(validate): + """Build and discard array.""" + + @compile_quantum_guppy + def test() -> None: + qs = array(qubit() for _ in range(10)) + discard_array(qs) + + validate(test) From 0c73b045dde07dec8e2e66ee17fc191e329a70b9 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Thu, 12 Dec 2024 13:21:56 +0000 Subject: [PATCH 3/3] use for loop Co-authored-by: Mark Koch <48097969+mark-koch@users.noreply.github.com> --- guppylang/std/quantum.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/guppylang/std/quantum.py b/guppylang/std/quantum.py index 2e0bac48..9925648a 100644 --- a/guppylang/std/quantum.py +++ b/guppylang/std/quantum.py @@ -155,8 +155,10 @@ def measure_array(qubits: array[qubit, N] @ owned) -> array[bool, N]: """Measure an array of qubits, returning an array of bools.""" return array(measure(q) for q in qubits) + @guppy @no_type_check def discard_array(qubits: array[qubit, N] @ owned) -> None: """Discard an array of qubits.""" - _ = array(discard(q) for q in qubits) + for q in qubits: + discard(q)