Quantum Operations¶
These examples cover Guppy features around measurement values, gate parameters, modifiers, and nearby helper operations.
Measurement objects¶
Source file: guppy_examples/guppy-features/supported/measurement-object.py
from typing import no_type_check
from guppylang import guppy
from guppylang.std.builtins import output, qubit
from guppylang.std.quantum import h, measure, x
@guppy
@no_type_check
def main() -> None:
control = qubit()
target = qubit()
h(control)
measurement = measure(control)
if measurement:
x(target)
output("measurement_read", measurement.read())
output("target", measure(target).read())
In Guppy v1, measure(q) returns a measurement object. It can be used as a conditional value, and the classical result should be passed to output by calling .read().
Angles¶
Source file: guppy_examples/guppy-features/supported/angles.py
from typing import no_type_check
from guppylang import guppy
from guppylang.std.angles import angle, pi
from guppylang.std.builtins import output, qubit
from guppylang.std.quantum import measure, rz
@guppy
@no_type_check
def main() -> None:
q = qubit()
theta = (pi / 2.0) + angle(0.25)
rz(q, theta)
output("angle", measure(q).read())
Dagger modifier¶
Source file: guppy_examples/guppy-features/supported/modifier-dagger.py
from typing import no_type_check
from guppylang import guppy
from guppylang.std.angles import pi
from guppylang.std.builtins import dagger, output, qubit
from guppylang.std.quantum import measure, rz, x
@guppy
@no_type_check
def main() -> None:
target = qubit()
with dagger():
rz(target, pi / 4.0)
x(target)
output("dagger_target", measure(target).read())
Control modifier¶
Source file: guppy_examples/guppy-features/supported/modifier-control.py
import sys
from typing import no_type_check
from guppylang import array, guppy
from guppylang.std.builtins import control, output, qubit
from guppylang.std.quantum import collect_measurements, cx, h, measure, measure_array, x
@guppy
@no_type_check
def controlled_x(ctl: qubit, target: qubit) -> None:
with control(ctl):
x(target)
@guppy
@no_type_check
def double_controlled_x(ctl: array[qubit, 2], target: qubit) -> None:
with control(ctl[0], ctl[1]):
x(target)
@guppy
@no_type_check
def main() -> None:
# single control
ctl = qubit()
target = qubit()
h(ctl)
controlled_x(ctl, target)
output("control_target", measure(target).read())
output("control_ctl", measure(ctl).read())
# double control
ctl2 = array(qubit(), qubit())
for i in range(2):
h(ctl2[i])
trg2 = qubit()
double_controlled_x(ctl2, trg2)
output("control_target_2", measure(trg2).read())
output("control_ctl2", collect_measurements(measure_array(ctl2)))
# multi control, multi target
ctlm = array(qubit() for _ in range(3))
for i in range(3):
h(ctlm[i])
targets = array(qubit() for _ in range(3))
with control(ctlm):
h(targets[0])
cx(targets[0], targets[1])
x(targets[2])
cx(targets[1], targets[2])
output("targets", collect_measurements(measure_array(targets)))
output("ctlm", collect_measurements(measure_array(ctlm)))
if __name__ == "__main__":
sys.stdout.buffer.write(main.compile().to_bytes())
Control modifiers are supported when the controlled operation can be resolved during compilation.
Barrier¶
Source file: guppy_examples/guppy-features/supported/barrier.py
from typing import no_type_check
from guppylang import array, guppy, qubit
from guppylang.std.builtins import output
from guppylang.std.platform import barrier
from guppylang.std.quantum import discard_array, h, measure
@guppy
@no_type_check
def main() -> None:
qbs = array(qubit() for _ in range(4))
h(qbs[0])
barrier(qbs[0])
h(qbs[0])
barrier(qbs)
q0, q1, *qbs = qbs
b = False
a = measure(q0).read()
if a:
h(q1)
b = measure(q1).read()
if b:
b = False
else:
b = measure(q1).read()
output("a", a)
output("b", b)
discard_array(qbs)
Barriers accept individual qubits and qubit arrays. Passing any non-qubit value will cause QIR generation to fail.
from typing import no_type_check
from guppylang import array, guppy, qubit
from guppylang.std.builtins import output
from guppylang.std.platform import barrier
from guppylang.std.quantum import discard_array, h, measure
@guppy
@no_type_check
def main() -> None:
qbs = array(qubit() for _ in range(4))
h(qbs[0])
barrier(qbs[0])
h(qbs[0])
barrier(qbs, 9)
q0, q1, *qbs = qbs
b = False
a = measure(q0).read()
if a:
h(q1)
b = measure(q1).read()
if b:
b = False
else:
b = measure(q1).read()
output("a", a)
output("b", b)
discard_array(qbs)
Expected error:
Compilation failed: H-series barriers cannot contain non-qubit types
Memory swap¶
Source file: guppy_examples/guppy-features/supported/mem-swap.py
from typing import no_type_check
from guppylang import guppy
from guppylang.std.builtins import output
from guppylang.std.mem import mem_swap
@guppy
@no_type_check
def main() -> None:
left = 1
right = 2
mem_swap(left, right)
output("swap_left", left)
output("swap_right", right)