Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Qamomile v0.12.1

Qamomile v0.12.1 is a follow-up release on top of v0.12.0, focused on frontend ergonomics and bug fixes. The frontend gains two ergonomic improvements — single-qubit gates can now broadcast over a Vector[Qubit] (so a whole-register layer is one line instead of an explicit loop), and sub-@qkernel call sites accept raw Python literals (int, float, bool) for UInt / Float / Bit parameters. QURI Parts now accepts linear combinations of parameters such as gamma * Jij, fixing a long-standing transpile error in the canonical QAOA pattern. Two compiler bugs are fixed (the QAOA-blocking nested-loop name collision, and the QURI Parts limitation above), and the qaoa_graph_partition tutorial is rewritten to use the OMMX SampleSet API end-to-end.

pip install qamomile==0.12.1

New Features

Broadcast single-qubit gates over qubit arrays

Single-qubit gates (h, x, y, z, s, t, sdg, tdg, rx, ry, rz, p) now accept a Vector[Qubit] directly, applying the gate to every element of the register. The broadcast form lowers to the same ForOperation that a hand-written for i in qmc.range(n): q[i] = qmc.h(q[i]) would emit (and analogously for any other single-qubit gate), so resource estimation, transpilation, and visualization all see the same IR — only the source is shorter. For rotation gates, the same scalar angle is shared across every qubit; per-qubit angles still need an explicit index loop into a Vector[Float] (#360).

import qamomile.circuit as qmc
from qamomile.qiskit import QiskitTranspiler


@qmc.qkernel
def rotation_layer_broadcast(n: qmc.UInt, theta: qmc.Float) -> qmc.Vector[qmc.Bit]:
    q = qmc.qubit_array(n, name="q")
    q = qmc.h(q)            # broadcast Hadamard over the whole register
    q = qmc.ry(q, theta)    # shared scalar angle over the whole register
    return qmc.measure(q)


transpiler = QiskitTranspiler()
exe = transpiler.transpile(
    rotation_layer_broadcast,
    bindings={"n": 4},
    parameters=["theta"],
)

See the updated Tutorial 02 — Parameterized Quantum Kernels for the broadcast section, which contrasts the broadcast and explicit-loop forms side by side.

Auto-promote scalar literals at sub-qkernel call sites

When a sub-@qkernel declares a scalar parameter typed qmc.UInt, qmc.Float, or qmc.Bit, the call site now accepts raw Python literals — int is promoted to UInt, int / float to Float, and bool to Bit. Writing helper(q, 0, 0.5) is equivalent to helper(q, qmc.uint(0), qmc.float_(0.5)). This mirrors the literal-acceptance pattern already used by built-in gate primitives such as qmc.rx, which has always accepted float | Float for its angle. As a beneficial side effect, scalar default values like def f(n: qmc.UInt = 4) now work without explicitly wrapping the default in a Handle constructor (#372).

The promotion is conservative. It triggers only when the declared type is exactly one of the three scalar Handle classes and the literal is the matching primitive. bool is intentionally excluded from the int → UInt and int → Float paths so that True cannot silently become UInt(1). Already-Handle arguments and array-typed parameters pass through unchanged, so existing symbolic-execution paths are unaffected.

import qamomile.circuit as qmc
from qamomile.qiskit import QiskitTranspiler


@qmc.qkernel
def rotate_first(
    q: qmc.Vector[qmc.Qubit],
    idx: qmc.UInt,
    angle: qmc.Float,
) -> qmc.Vector[qmc.Qubit]:
    q[idx] = qmc.ry(q[idx], angle)
    return q


@qmc.qkernel
def helper_with_literals(n: qmc.UInt) -> qmc.Vector[qmc.Bit]:
    q = qmc.qubit_array(n, name="q")
    q = rotate_first(q, 0, 0.5)   # int and float literals are accepted directly
    return qmc.measure(q)


transpiler = QiskitTranspiler()
exe = transpiler.transpile(helper_with_literals, bindings={"n": 3})

See the updated Tutorial 06 — Reuse Patterns, which now covers the literal-promotion convenience explicitly.

Bug Fixes

Documentation

Learn More