[Basic] FTQC Resource Estimation with Quration¶
This document explains how to perform resource estimation at the instruction set level of an FTQC architecture (surface code and lattice surgery) using quration for circuits written with qsub.
The overall workflow is as follows:
Write a circuit with qsub
↓
Convert the qsub circuit to a quration circuit
↓
Compile the quration circuit to ISA (instruction set)
↓
Perform resource estimation on the compiled code using qret
# If quri-parts with the qret extra is not installed, install it with the following command:
# %pip install "quri-parts[qret]"
Write a 2-qubit CNOT circuit with Qsub¶
from quri_parts.qsub.sub import SubBuilder
from quri_parts.qsub.lib.std import X, CNOT, Controlled
from quri_parts.qsub.visualize import draw
from quri_parts.qsub.resolve import resolve_sub
ctrl = Controlled(X)
sub = resolve_sub(ctrl)
draw(sub)
Resource Estimation with qsub (CNOT)¶
Before going through quration, we can already get logical-level resource estimates (qubit count, gate count) directly from qsub. See the qsub tutorial for details.
# Compile the CNOT
from quri_parts.qsub.compile import compile_sub
from quri_parts.qsub.evaluate import Evaluator
from quri_parts.qsub.eval import GateCountEvaluatorHooks, TotalQubitCountEvaluatorHooks, QURIPartsEvaluatorHooks
from quri_parts.qsub.primitive import AllBasicSet
compiled = compile_sub(sub, AllBasicSet)
qubit_counter = Evaluator(TotalQubitCountEvaluatorHooks())
required_qubits = qubit_counter.run(compiled)
print(f"total qubit count: {required_qubits}")
gate_counter = Evaluator(GateCountEvaluatorHooks(AllBasicSet))
gate_count = gate_counter.run(compiled)
print({k[1]: v for k, v in gate_count.items()})
total qubit count: 2
{'CNOT': 1}
Compilation to Surface Code / Lattice Surgery Architecture¶
What are the IR and ISA?¶
The qsub circuit is first converted into quration’s IR (Intermediate Representation), a hardware-independent description of the logical circuit (qubit allocations and logical gates).
The Quration compiler then lowers the IR into ISA (Instruction Set Architecture) code: a set of low-level instructions that a specific hardware architecture can execute directly. Here it targets instructions specific to the surface code / lattice surgery architecture (such as LATTICE_SURGERY and ALLOCATE). Compiling refers to this conversion from the IR to ISA.
Compilation Flow¶
The Quration compiler converts a logical quantum circuit into a sequence of instructions on the surface code / lattice surgery architecture. The process consists of three stages:
1. Mapping¶
Assigns logical qubits to logical cells (coordinates) on the chip.
2. Routing¶
Lattice surgery between non-adjacent logical qubits is implemented as a chain of lattice surgery operations via path cells.
The difference between runtime and runtime_without_topology corresponds to this routing overhead.
3. Scheduling and Profiling¶
Simulates the lattice surgery instruction sequence beat by beat (timestep by timestep) and computes performance metrics such as execution time, number of physical qubits, and magic state consumption count.
To convert to wall-clock time (seconds), the code cycle time (code_cycle_time_sec), calibrated for a superconducting device, is specified in the pipeline.
Example: Conversion of a Logical CNOT to Lattice Surgery¶
A logical CNOT is realized as two parity measurements, ZZ and XX.
Logical CNOT(q0→q1)
↓
[beat 0] LATTICE_SURGERY [q1, q0] ZZ measurement → classical bit c10
[beat 1] LATTICE_SURGERY [q1, q0] XX measurement → classical bit c11
Each measurement result (c10, c11) determines whether a byproduct Pauli correction is needed. However, since CNOT is a Clifford gate, the byproduct can be classically tracked via Pauli frame tracking and no actual quantum correction operation is required (measurement_feedback_count = 0).
The _assets/basic_resource_estimation/compiled_cnot.json inspected in a later step contains these two LATTICE_SURGERY instructions.
Resource Estimation with quration¶
Please install qret CLI (needed for compile, profile, and visualization of quration IR/ISA) via the following command
# Install qret-cli-bundle
# %pip install git+https://github.com/QunaSys/quration-cli-bundle.git
qret_cli_bundle.ensure_qret_on_path() makes the bundled qret and gridsynth binaries available to the current session. On first call it downloads the binaries for your platform; it appends their location to PATH (and the library search path). Run it once before any step that invokes qret: IR conversion, qret compile, and qret profile all rely on these binaries being discoverable.
import qret_cli_bundle
qret_cli_bundle.ensure_qret_on_path()
import quri_parts.qret.convert_qsub as converter
import pyqret
cnot_module = converter.create_module_from_qsub_op(entry_op=ctrl)
# Dump the converted quration IR to a JSON file
cnot_module.dump("_assets/basic_resource_estimation/cnot_ir.json")
This is purely cosmetic (for readability) and not required by the workflow.
import json
def beautifyJSON(filename):
with open(filename, "r") as f:
data = json.load(f)
with open(filename, "w") as f:
json.dump(data, f, indent=4)
beautifyJSON("_assets/basic_resource_estimation/cnot_ir.json")
IR file genereated is shown below.
%cat _assets/basic_resource_estimation/cnot_ir.json
{
"metadata": {
"format": "IR",
"schema_version": "0.1",
"qret_version": "1.0.1",
"created_at": "2026-06-09T13:50:24"
},
"name": "__qsub__lib.std.Controlled<lib.std.X>",
"circuit_list": [
{
"name": "lib.std.Controlled<lib.std.X>",
"entry_point": "entry",
"bb_list": [
{
"name": "entry",
"inst_list": [
{
"opcode": "CX",
"q0": 1,
"q1": 0
},
{
"opcode": "Return"
}
],
"predecessors": [],
"successors": []
}
],
"argument": {
"num_qubits": 2,
"qubits": {
"q0": 1,
"q1": 1
},
"num_registers": 0
},
"num_tmp_registers": 0
}
]
}
Defining the Topology¶
Before compilation, you need to define the layout of logical qubits and magic factories on the chip. Quration calls this the “topology”.
There are three types of cells in a topology:
Cell type |
Role |
How to configure |
|---|---|---|
Data logical qubit cell (Q) |
Location of the algorithm’s logical qubits |
Placed automatically by qret |
Ancilla cell (.) |
Ancilla cells used as routing paths for lattice surgery |
Placed automatically by qret |
Magic factory cell (M) |
Cells that produce magic states required for T-gates |
Must be defined in the topology file |
M . M . M (Q = data logical qubit cell, . = ancilla cell, M = magic factory cell)
. . . . .
Q . Q . Q
. . . . .
Q . Q . .
The topology file can be auto-generated from the qubit count estimated on the qsub side, or prepared manually.
Required qubit count = input/output qubit count + auxiliary qubit count
Auto-generated topology files may have room for optimization. E.g.) Carefully placed magic factory can shorten the delivery of T gate to each qubit.
import quri_parts.qret.topology_utils as topology
topology.write_generated_topology("_assets/basic_resource_estimation/topology_for_cnot.yaml", required_qubits, magic_factory_count=1)
%cat _assets/basic_resource_estimation/topology_for_cnot.yaml
grids:
- type: plane
coord: [3, 3, 0]
magic_factory:
- symbol: 0
coord: [0, 0]
Compile the quration IR to ISA¶
First confirm that qret cli is on the PATH, then compile using the pipeline file.
import qret_cli_bundle
qret_cli_bundle.ensure_qret_on_path()
To compile an IR file to the ISA (instruction set) level using the qret CLI, you need to prepare a pipeline file.
The pipeline mainly specifies:
source: format of the input file (IR, QASM, etc.)input: input file pathoutput: output file pathtarget: target machine architecturefunction: name of the entry-point function in the circuit. When converting from qsub,maincan usually be specified.sc_ls_fixed_v0_topology: topology file path
At the moment, the pipeline file must be prepared manually.
# Contents of _assets/basic_resource_estimation/cnot_pipeline.yaml
%cat _assets/basic_resource_estimation/cnot_pipeline.yaml
source: IR
input: _assets/basic_resource_estimation/cnot_ir.json
function: main
target: SC_LS_FIXED_V0
output: _assets/basic_resource_estimation/compiled_cnot.json
sc_ls_fixed_v0_topology: _assets/basic_resource_estimation/topology_for_cnot.yaml
sc_ls_fixed_v0_machine_type: Dim2
sc_ls_fixed_v0_magic_generation_period: 15
sc_ls_fixed_v0_maximum_magic_state_stock: 10000
sc_ls_fixed_v0_entanglement_generation_period: 100
sc_ls_fixed_v0_maximum_entangled_state_stock: 10
sc_ls_fixed_v0_reaction_time: 1
sc_ls_fixed_v0_drop_rate: 0.1
sc_ls_fixed_v0_code_cycle_time_sec: 0.00000001
sc_ls_fixed_v0_physical_error_rate: 0.01
sc_ls_fixed_v0_allowed_failure_prob: 0.01
sc_ls_fixed_v0_pass:
- sc_ls_fixed_v0::init_compile_info
- sc_ls_fixed_v0::mapping
- sc_ls_fixed_v0::routing
%%sh
# Compile _assets/basic_resource_estimation/cnot_ir.json
qret compile --pipeline _assets/basic_resource_estimation/cnot_pipeline.yaml
Profile the generated ISA file
%%sh
# Profile _assets/basic_resource_estimation/cnot_ir.json
qret profile -i _assets/basic_resource_estimation/compiled_cnot.json -o _assets/basic_resource_estimation/profiled_cnot.json
Viewing Profiling Results with the Quration Visualizer¶
Computational Process Visualizer¶
Visualizes the execution trace (computational process) of a quantum program. You can follow the execution status of instructions beat by beat (timestep by timestep) in an animated fashion.
Launch the computational process visualizer and load _assets/basic_resource_estimation/compiled_cnot.json from the Web UI.
qret_cli_bundle.visualize_computational_process()
Compile Info Visualizer¶
Displays and compares various information from post-compilation profile data across multiple profiles simultaneously.
Load _assets/basic_resource_estimation/profiled_cnot.json from the Web UI to view the profile information.
qret_cli_bundle.visualize_compile_info()
Key Metrics in Compile Info¶
The table below summarizes the metrics displayed in the compile info visualizer.
Runtime metrics¶
Metric |
Description |
|---|---|
|
Total execution time (seconds) calculated from the parameters given at compile time |
|
Total beat count (number of timesteps) including topology constraints |
|
Total beat count without topology constraints. A large difference from |
Hardware cost metrics¶
Metric |
Description |
|---|---|
|
Total number of physical qubits required |
|
Error-correcting code distance, determined by |
|
Total number of cells on the chip excluding magic factories |
|
Peak fraction of chip area occupied by algorithmic qubits. Lower values mean worse space efficiency (more cells used for routing/factories) |
|
Cumulative sum over beats of the number of active qubits (logical + ancilla); a measure of the algorithm’s spacetime volume, used to compare implementations |
Magic state metrics¶
Metric |
Description |
|---|---|
|
Total number of magic states consumed during logical circuit execution; the dominant metric for algorithm complexity |
|
Depth of the dependency chain of magic state consumption (number of serialized layers); a lower bound that cannot be reduced by parallelization |
|
Average magic state consumption per unit time. If well below the total factory production rate, |
|
Peak magic state consumption per unit time. If peak demand exceeds factory supply, queueing increases |
|
Number of magic state factories. Increasing it raises supply capacity but also space cost |
Measurement feedback metrics¶
Metric |
Description |
|---|---|
|
Total number of operations involving measurement feedback (scale of the adaptive circuit) |
|
Depth of measurement feedback operations. |
|
Peak frequency of feedback. Used to diagnose bottlenecks in the classical control system |
Gate statistics¶
Metric |
Description |
|---|---|
|
Total number of logical gates |
|
Breakdown by gate type. The ratio of T-gates to Clifford gates gives a rough estimate of FTQC cost |
|
Logical circuit depth (number of gate operations that must be executed sequentially). Correlated with runtime; more parallelism means smaller |