Getting Started¶
This tutorial walks through GraphQOMB’s main compiler path:
describe a computation with a circuit,
derive compiler IR objects,
lower them to an executable pattern,
inspect schedule-dependent metrics,
simulate the result.
If you prefer a runnable script first, start with From Circuit to Executable Pattern.
Compiler pipeline¶
GraphQOMB separates the main MBQC compilation steps into explicit objects:
a labelled graph state,
a scheduler describing executable time slices.
These are lowered with graphqomb.qompiler.qompile() into a graphqomb.pattern.Pattern.
Build an MBQC-native circuit¶
Use graphqomb.circuit.MBQCCircuit when you want an MBQC-native circuit description:
import numpy as np
from graphqomb.circuit import MBQCCircuit
circuit = MBQCCircuit(3)
circuit.j(0, 0.5 * np.pi)
circuit.cz(0, 1)
circuit.cz(0, 2)
circuit.j(1, 0.75 * np.pi)
circuit.j(2, 0.25 * np.pi)
For circuit descriptions that use macro gates such as H, CNOT, or Rz, see Circuit-Side Simulation Examples.
Derive compiler IRs¶
Use graphqomb.circuit.circuit2graph() to derive the graph-state IR, feedforward map, and a schedule seed from the circuit:
from graphqomb.circuit import circuit2graph
graphstate, xflow, scheduler = circuit2graph(circuit)
print("graph nodes:", len(graphstate.physical_nodes))
print("graph edges:", len(graphstate.physical_edges))
print("feedforward entries:", len(xflow))
print("scheduled slices:", scheduler.num_slices())
At this stage:
graphstatecarries the resource graph, measurement bases, and I/O registration,xflowstores explicit classical dependencies,schedulerstores prepare/entangle/measure slice timing.
Lower to an executable pattern¶
Lower these IR objects with graphqomb.qompiler.qompile():
from graphqomb.qompiler import qompile
pattern = qompile(graphstate, xflow, scheduler=scheduler)
print("pattern depth:", pattern.depth)
print("pattern max space:", pattern.max_space)
print("pattern active volume:", pattern.active_volume)
Passing scheduler is optional. If you omit it, graphqomb.qompiler.qompile()
constructs a graphqomb.scheduler.Scheduler internally, solves it with the
default MINIMIZE_TIME strategy, and still emits TICK-delimited time slices.
By default, graphqomb.qompiler.qompile() derives zflow from odd neighborhoods when you do not pass it explicitly. This is convenient for standard deterministic workflows, while still allowing explicit zflow control when you need a custom feedforward design.
The resulting graphqomb.pattern.Pattern contains:
scheduled commands,
resource metrics such as
depth,max_space, andactive_volume.
Inspect the result¶
Patterns can be inspected directly:
from graphqomb.pattern import print_pattern
print_pattern(pattern, lim=20)
print("space profile:", pattern.space)
The emitted command stream is sliced with TICK markers according to the active
schedule. This happens both when you provide scheduler explicitly and when
graphqomb.qompiler.qompile() creates one internally with its default
strategy. Those slice boundaries are the executable schedule seen by pattern
simulators and downstream exporters.
Simulate the pattern¶
Use graphqomb.simulator.PatternSimulator for direct execution:
from graphqomb.simulator import PatternSimulator, SimulatorBackend
simulator = PatternSimulator(pattern, SimulatorBackend.StateVector)
simulator.simulate()
state = simulator.state.state()
For deeper validation against the source circuit, see From Circuit to Executable Pattern, which compares circuit and pattern simulation results.
Where to go next¶
Architecture Overview explains the three-IR compiler model and the lowering semantics.
Scheduler IR and Execution Tradeoffs compares space- and time-oriented scheduling strategies.
Entanglement Scheduling and TICK Slices focuses on explicit entanglement timing and
TICKslices.Stim Compiler documents the Stim export path for compatible patterns.