Migrating from Qiskit Transpiler¶
If you’re already using Qiskit’s transpile() or generate_preset_pass_manager(),
this guide shows how to integrate qb-compiler with minimal changes.
Option 1: Drop-in Replacement¶
Replace transpile() with qb_transpile():
Before (Qiskit only):
from qiskit import QuantumCircuit, transpile
qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.measure_all()
compiled = transpile(qc, backend=backend, optimization_level=3)
After (qb-compiler):
from qiskit import QuantumCircuit
from qb_compiler.qiskit_plugin import qb_transpile
qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.measure_all()
compiled = qb_transpile(qc, backend="ibm_fez")
The returned circuit is a standard Qiskit QuantumCircuit that you can
submit to any Qiskit runtime as before.
Option 2: passmanager() Factory¶
One-liner that returns a ready StagedPassManager with calibration-aware
layout injected:
from qb_compiler import passmanager
pm = passmanager(backend) # accepts Backend, Target, or name string
compiled = pm.run(circuit)
Option 3: QBCalibrationPass as a Qiskit TransformationPass¶
QBCalibrationPass subclasses Qiskit’s TransformationPass, so it
slots into any PassManager or StagedPassManager:
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qb_compiler.qiskit_plugin import QBCalibrationPass
pm = generate_preset_pass_manager(optimization_level=3, target=backend.target)
pm.layout.append(QBCalibrationPass(backend=backend))
compiled = pm.run(circuit)
The pass accepts a Backend or Target at init and uses live
calibration data for layout selection and gate cancellation.
Option 4: QBCalibrationLayout AnalysisPass¶
Keep your existing pass manager and add qb-compiler’s calibration-aware layout as an analysis pass using a calibration JSON file:
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qb_compiler.qiskit_plugin import QBCalibrationLayout
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
pm.layout.append(QBCalibrationLayout(calibration_data))
compiled = pm.run(circuit)
Option 5: Full QBCompiler API¶
For maximum control, use the QBCompiler API directly and convert back to Qiskit when needed:
from qb_compiler import QBCompiler, QBCircuit
compiler = QBCompiler.from_backend("ibm_fez")
circ = QBCircuit(3).h(0).cx(0, 1).cx(1, 2).measure_all()
result = compiler.compile(circ)
# Get a Qiskit QuantumCircuit for submission
qiskit_circuit = result.compiled_circuit.to_qiskit()
# Submit to Qiskit Runtime as usual
# job = sampler.run(qiskit_circuit)
Key Differences from Qiskit¶
Feature |
Qiskit |
qb-compiler |
|---|---|---|
Layout selection |
Topology-based (SabreLayout) |
Calibration-weighted VF2 |
SWAP routing |
Minimise SWAP count (SabreSwap) |
Minimise accumulated error (Dijkstra) |
Scheduling |
ALAP/ASAP (static) |
T1/T2 urgency-weighted ALAP |
Fidelity estimate |
Not included |
Included in |
Cost estimate |
Not included |
Included with |
Budget enforcement |
Not included |
|
Multi-vendor |
IBM only |
IBM, Rigetti, IonQ, IQM |
What Stays the Same¶
qb-compiler uses Qiskit’s
QuantumCircuittype. No conversion needed.Gate decomposition uses the same native basis gates.
The output circuit is submission-ready for Qiskit Runtime.
All standard Qiskit gates are supported.
What You Gain¶
+2–5% estimated fidelity from calibration-aware mapping on IBM backends
Cost estimation before execution
Budget enforcement to prevent surprise bills
Multi-vendor support from a single API
Pre-execution fidelity prediction to know if your circuit is viable