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())

Unsupported: control modifier

Source file: guppy_examples/guppy-features/unsupported/modifier-control.py

import sys
from typing import no_type_check

from guppylang import guppy
from guppylang.std.builtins import control, output, qubit
from guppylang.std.quantum import h, measure, x


@guppy
@no_type_check
def main() -> None:
    ctl = qubit()
    target = qubit()
    h(ctl)

    # The control modifier lowers to an array of control qubits, which is not
    # currently supported by QIR lowering.
    with control(ctl):
        x(target)

    output("control_target", measure(target).read())
    output("control_ctl", measure(ctl).read())


if __name__ == "__main__":
    sys.stdout.buffer.write(main.compile().to_bytes())

The control modifier lowers to an array of control qubits, which is not currently supported by QIR lowering.

Expected error:

QIR generation failed. This may be the result of a bug but can also happen when trying to convert a feature in HUGR/Guppylang which is not supported in QIR. Error details: Failed to emit LLVM for function guppy_example_mod.main at node Node(1)

Caused by:
    Unknown type: array(1, qubit)

Unsupported: barrier

Source file: guppy_examples/guppy-features/unsupported/barrier.py

from typing import no_type_check

from guppylang import guppy, qubit
from guppylang.std.builtins import output
from guppylang.std.platform import barrier
from guppylang.std.quantum import h, measure


@guppy
@no_type_check
def main() -> None:
    q0, q1 = qubit(), qubit()
    h(q0)
    barrier(q0)
    h(q0)
    a = measure(q0).read()
    b = False
    if a:
        h(q1)
        b = measure(q1).read()
        if b:
            b = False
    else:
        b = measure(q1).read()
    output("a", a)
    output("b", b)

The current lowering path for barriers also introduces array-typed values, so barriers are not currently supported in the H-Series QIR subset.

Expected error:

QIR generation failed. This may be the result of a bug but can also happen when trying to convert a feature in HUGR/Guppylang which is not supported in QIR. Error details: Failed to emit LLVM for function guppy_example_mod.main at node Node(1)

Caused by:
    0: Failed to emit LLVM for node N<CFG:Node(4)> with optype CFG
    1: Failed to emit LLVM for node N<DFG:Node(64)> with optype DFG
    2: Unknown type: array(1, qubit)

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)