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.

Resource Estimation

Before running a quantum kernel on real hardware, you may want to know its required resources, such as qubit count and gate count. Or, you may want to know the resource requirements of a quantum kernel you defined in the first place. Qamomile’s estimate_resources() fills this need without executing the qkernel. It works with both concrete and symbolic (parameterized) qkernels.

This chapter covers:

  • Basic resource estimation for fixed qkernels

  • Symbolic resource estimation for parameterized qkernels

  • The full ResourceEstimate field reference

  • Scaling analysis with .substitute()

# Install the latest Qamomile through pip!
# !pip install qamomile
import qamomile.circuit as qmc

Estimating Resources of a Fixed QKernel

For a qkernel with no parameters, estimate_resources() returns concrete numbers.

@qmc.qkernel
def fixed_circuit() -> qmc.Vector[qmc.Bit]:
    q = qmc.qubit_array(3, name="q")

    q[0] = qmc.h(q[0])
    q[0], q[1] = qmc.cx(q[0], q[1])
    q[1], q[2] = qmc.cx(q[1], q[2])

    return qmc.measure(q)
fixed_circuit.draw()
<Figure size 785.5x256 with 1 Axes>
est = fixed_circuit.estimate_resources()
print("qubits:", est.qubits)
print("total gates:", est.gates.total)
print("single-qubit gates:", est.gates.single_qubit)
print("two-qubit gates:", est.gates.two_qubit)
qubits: 3
total gates: 3
single-qubit gates: 1
two-qubit gates: 2

Symbolic Resource Estimation

When a qkernel has unbound parameters (like n: qmc.UInt), estimate_resources() returns SymPy expressions that show how costs scale with the parameter. This lets you analyze scaling without picking a specific value.

@qmc.qkernel
def scalable_circuit(n: qmc.UInt, theta: qmc.Float) -> qmc.Vector[qmc.Bit]:
    q = qmc.qubit_array(n, name="q")

    for i in qmc.range(n):
        q[i] = qmc.h(q[i])
        q[i] = qmc.ry(q[i], theta)

    for i in qmc.range(n - 1):
        q[i], q[i + 1] = qmc.cx(q[i], q[i + 1])

    return qmc.measure(q)
scalable_circuit.draw(n=4, fold_loops=False)
<Figure size 1044.5x336 with 1 Axes>
est = scalable_circuit.estimate_resources()
print("qubits:", est.qubits)
print("total gates:", est.gates.total)
print("single-qubit gates:", est.gates.single_qubit)
print("two-qubit gates:", est.gates.two_qubit)
print("rotation gates:", est.gates.rotation_gates)
print("parameters:", est.parameters)
qubits: n
total gates: 3*n - 1
single-qubit gates: 2*n
two-qubit gates: n - 1
rotation gates: n
parameters: {'n': n}

The output contains SymPy expressions like n for qubits and 3*n - 1 for total gates. These are exact — not approximations.

ResourceEstimate Fields Reference

FieldDescription
est.qubitsLogical qubit count
est.gates.totalTotal gate count
est.gates.single_qubitSingle-qubit gates
est.gates.two_qubitTwo-qubit gates
est.gates.multi_qubitMulti-qubit gates (3+ qubits)
est.gates.t_gatesT-gate count
est.gates.clifford_gatesClifford gate count
est.gates.rotation_gatesRotation gate count
est.gates.oracle_callsOracle call counts (dict by name)
est.parametersDict of symbol names → SymPy symbols

All fields are SymPy expressions. For fixed qkernels they evaluate to plain integers.

Scaling Analysis with .substitute()

The symbolic expressions tell you the formula, but often you want concrete numbers at specific sizes. Use .substitute() to evaluate:

for n_val in [4, 8, 16, 32]:
    c = est.substitute(n=n_val)
    print(
        f"n={n_val:2d}: {int(c.gates.total):>3} gates total, {int(c.gates.two_qubit):>2} two-qubit"
    )
n= 4:  11 gates total,  3 two-qubit
n= 8:  23 gates total,  7 two-qubit
n=16:  47 gates total, 15 two-qubit
n=32:  95 gates total, 31 two-qubit

Summary

  • estimate_resources() reports qubit and gate costs without executing.

  • For parameterized qkernels, results are SymPy expressions showing exact scaling.

  • Use .substitute(n=...) to evaluate at specific sizes and check feasibility.

Next: Execution Modelssample() vs run(), observables, and bit ordering.