Error Mitigation Recipe Generator for Mitiq.
EMRG reads a quantum circuit, chooses the right mitigation recipe, and renders the Mitiq code to run it. Qiskit and QASM are native, Cirq is supported directly, and Braket, PennyLane, PyQuil, and Qibo can be used through Mitiq/Cirq normalization.
NISQ error mitigation has too many knobs. ZNE needs scale factors and a folding method. PEC needs a noise model and a sampling budget. CDR needs enough non-Clifford structure to train against. Composite recipes can help, but only when their cost is still sane. It is a problem that I myself faced.
EMRG is a recipe layer.
It inspects a circuit, picks from ZNE, PEC, CDR, or composite ZNE-over-PEC, then outputs Mitiq-native Python with the reason for the choice. It is intentionally made boring: inspect, choose, render.
Qiskit / QASM / Cirq / converted frontend
|
v
analyze features -> choose policy recipe -> render Mitiq code -> optional preview
- Analyze circuit features: depth, gate mix, noise proxy, PEC overhead, layer heterogeneity, and non-Clifford fraction. Qiskit and QASM use the native Qiskit path, Cirq is analyzed directly, and optional frontends are converted through Mitiq/Cirq first.
- Pick a recipe from the active policy.
- Generate Mitiq code with imports, parameters, and rationale.
- Optionally preview the recipe with a local simulator.
pip install emrgFrom a source checkout:
emrg analyze docs/examples/bell_state.qasm
emrg generate docs/examples/bell_state.qasmPython:
from qiskit import QuantumCircuit
from emrg import generate_recipe
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
result = generate_recipe(qc)
print(result.code)
print(result.rationale)Cirq:
import cirq
from emrg import generate_recipe
q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(cirq.H(q0), cirq.CNOT(q0, q1), cirq.measure(q0, q1))
result = generate_recipe(circuit)
print(result.code)The generated script contains a backend executor adapter. You still connect that adapter to your simulator or hardware backend.
| Input | Status | Notes |
|---|---|---|
Qiskit QuantumCircuit |
native | Main Python API path |
| QASM files/stdin | native | CLI path, loaded through Qiskit |
Cirq Circuit |
direct | Python API |
Braket Circuit |
experimental normalized | converted through Mitiq/Cirq |
PennyLane QuantumTape |
experimental normalized | QNodes are not the target yet |
PyQuil Program |
experimental normalized | converted through Mitiq/Cirq |
Qibo Circuit |
experimental normalized | converted through Mitiq/Cirq |
For normalized frontends, EMRG analyzes the Mitiq/Cirq-normalized circuit. Depth, gate counts, and non-Clifford counts may differ from native SDK semantics. The CLI is still QASM-only; other frontends are Python API inputs.
Optional installs:
pip install "emrg[preview]"
pip install "emrg[config]"
pip install "emrg[braket]"
pip install "emrg[pennylane]"
pip install "emrg[pyquil]"
pip install "emrg[qibo]"
pip install "emrg[frontends]"emrg[frontends] installs the optional converted frontend stack in one shot.
# Generate mitigation recipe from a QASM file
emrg generate circuit.qasm
# With verbose explanation
emrg generate circuit.qasm --explain
# Save to file
emrg generate circuit.qasm -o mitigated.py
# Create and validate a policy file
emrg policy init emrg-policy.json
emrg policy validate emrg-policy.json
# Generate with a policy file
emrg generate circuit.qasm --policy emrg-policy.json
# Force a specific technique
emrg generate circuit.qasm --technique pec --noise-model
emrg generate circuit.qasm --technique composite --noise-model
emrg generate circuit.qasm --technique cdr
# Forced techniques bypass automatic viability checks. EMRG still returns the
# requested recipe, but generated output includes warnings when the circuit
# falls outside the automatic selection criteria.
# Preview: simulate and compare before/after mitigation
emrg generate circuit.qasm --preview
# Preview with custom noise level and observable
emrg generate circuit.qasm --preview --noise-level 0.03 --observable ZZ
# Analyze circuit features
emrg analyze circuit.qasm
# JSON output (for scripting)
emrg analyze circuit.qasm --json
EMRG has a built-in default policy. Policies tune thresholds, overhead budgets, and Mitiq factory/scaling choices. Policies are data, not code: they do not execute Python, import modules, or define arbitrary logic.
JSON policies work in the base install. YAML policies require:
pip install "emrg[config]"Smallest useful flow:
emrg policy init emrg-policy.json
emrg policy validate emrg-policy.json
emrg generate circuit.qasm --policy emrg-policy.jsonUse the generated policy file as the schema reference. The implementation lives
in src/emrg/policy.py.
Preview mode runs a local simulator check for Qiskit and Cirq inputs:
pip install "emrg[preview]"
emrg generate docs/examples/bell_state.qasm --previewIt uses density-matrix simulation, so size matters. Circuits above the preview budget are skipped with a plain warning. PEC, CDR, and composite previews can vary because they include stochastic pieces. For Braket, PennyLane, PyQuil, and Qibo inputs, recipe generation works but preview is intentionally skipped for now.
v0.6.0 includes a reproducible local benchmark harness. It compares policy choices under simulator and noise-model setups. This is useful for regression testing and local policy calibration. It is not a hardware performance claim.
Compact local calibration snapshot:
| Policy | Score | Median error reduction | Failures | Skips |
|---|---|---|---|---|
default-v050.json |
0.7872 | 2.357x | 0 | 8/18 |
default-v051.json |
1.8455 | 4.779x | 0 | 8/18 |
Benchmark numbers are local simulator results. Run
benchmarks/run_benchmark.py to write machine-readable JSON under
benchmarks/results/, then score it with benchmarks/score_results.py.
Skipped simulations are recorded, not counted as passes.
Older detailed benchmark tables live in
benchmarks/HISTORICAL_RESULTS.md.
EMRG/
|-- src/emrg/
| |-- __init__.py # Public API and generate_recipe()
| |-- _version.py # Single source of truth for version
| |-- analyzer.py # Circuit feature extraction
| |-- frontends.py # Frontend detection and normalization
| |-- heuristics.py # Rule-based decision engine
| |-- policy.py # JSON/YAML policy model and validation
| |-- codegen.py # Template-based code generation
| |-- preview.py # Simulation preview engine
| |-- cli.py # Click CLI interface
| `-- py.typed # PEP 561 type marker
|-- tests/ # Unit, integration, frontend, benchmark, and docs checks
|-- docs/
| |-- examples/ # Example circuits (Python + QASM)
| |-- tutorials/ # Jupyter notebooks (VQE, QAOA)
| `-- banner-emrg.jpg # Cool README banner
|-- benchmarks/ # Automated benchmark suite plus historical data
|-- tools/ # Maintainer checks for optional frontend extras
`-- pyproject.toml # Package configuration
- Deterministic by default.
- Policy files, not arbitrary code.
- Mitiq-native output instead of a wrapper runtime.
- Qiskit/QASM native, Cirq direct, optional frontends normalized through Mitiq/Cirq.
- Benchmark harness is local and reproducible.
- Conservative about hardware claims.
- Converted frontend analysis uses Cirq-normalized features, so counts may differ from native SDK semantics.
- CLI input is QASM-only.
- Generated code needs a backend executor.
- Preview is Qiskit/Cirq simulation, not hardware validation.
- PEC, CDR, and composite recipes can have stochastic or backend-specific costs.
- Native analyzers for optional frontends are future work only if conversion proves insufficient.
- Project structure and packaging
- Circuit analyzer (feature extraction)
- Heuristic engine (ZNE: Linear + Richardson + Poly)
- Code generator (template-based)
- CLI with
generateandanalyzecommands - Public Python API (
generate_recipe()) - Example circuits (Python + QASM) and documentation
- Probabilistic Error Cancellation (PEC) support
- Multi-technique selection (ZNE vs PEC)
- PEC code generation template
-
--techniqueoverride and--noise-modelCLI flags - Layerwise Richardson integration
-
--previewmode (noisy simulation + before/after comparison) - Expanded tutorials (VQE, QAOA)
- Unit, integration, preview, policy, and docs checks in CI/local validation
- Clifford Data Regression (CDR) support
- Composite recipes -- combine ZNE + PEC for circuits that benefit from both
- Configurable heuristics via YAML/JSON
- Cirq Python API input support
- Experimental normalized Braket, PennyLane QuantumTape, PyQuil Program, and Qibo Circuit input support
- Noise model import from Qiskit Aer / real device calibration data
- Jupyter widget for interactive recipe exploration
- Web/Colab interface
- Train on benchmark data to predict optimal mitigation strategy
- Circuit similarity search against known-good configurations
- Auto-tuning via internal
--previewiterations before output - Cost-aware optimization within user-specified shot budgets
- Real hardware benchmarks (IBM Quantum devices)
- Qiskit Runtime integration
- Mitiq Calibration API integration
- VS Code extension for inline circuit analysis
- CI/CD integration for quantum testing pipelines
- Python 3.11+
- Qiskit >= 1.0 -- circuit representation and introspection
- Mitiq >= 0.48 -- error mitigation primitives
- Click >= 8.0 -- CLI framework
- Cirq >= 1.0 -- direct Python input and simulation preview backend
- Braket, PennyLane, PyQuil, Qibo -- optional converted frontend extras
Open an issue or PR on GitHub. Always welcome!
MIT - go build something quantum!
Built on Mitiq by Unitary Foundation.
