Backend-neutral optimization and rewriting engine for the RQM ecosystem.
rqm-compiler owns the internal compiler circuit model and the optimization pipeline. The canonical external/public circuit schema is defined by rqm-circuits; rqm-compiler is the next layer after that boundary.
This project uses quaternions because they preserve more of what physical systems are doing: phase, rotation, orientation, polarization, and coherence. Standard complex-number methods are powerful, but they can flatten these relationships too early. Quaternionic coordinates keep them together as one structured object, giving software a richer view of the measured system.
For RQM Technologies, better coordinates mean better measurement: more informative diagnostics, cleaner transformations, and more precise control across quantum, wave, sensing, imaging, and communications workflows.
pip install rqm-compilerOr in development mode from the repository root:
pip install -e ".[dev]"Note for external integrations: Callers coming from the RQM API, Studio, or any external integration will typically enter the ecosystem through rqm-circuits, which owns the canonical public circuit schema. rqm-compiler is the next layer: it receives a parsed/validated circuit object and runs the optimization pipeline before handing off to a backend adapter.
from rqm_compiler import Circuit, optimize_circuit, lower_circuit_for_backend
c = Circuit(2)
c.h(0)
c.cx(0, 1)
c.measure_all()
# Recommended: optimize and export
optimized, report = optimize_circuit(c)
print(report)
# Optional backend-targeted lowering stage (example: Braket gate model).
# Internal optimization IR remains canonical u1q unless this is requested.
lowered = lower_circuit_for_backend(optimized, backend_family="braket_gate_model")
descriptors = lowered.to_descriptors()rqm-compiler exposes a tiered API. Most users should use Tier 1. Lower tiers exist for transformations and advanced workflows.
| Tier | Entrypoint | When to use | Stability |
|---|---|---|---|
| 1 — Build | Circuit, Operation |
Construct programs in the compiler's internal model | Stable |
| 2 — Transform | compile_circuit(...), optimize_circuit(...), lower_circuit_for_backend(...), compile_for_backend(...) |
Run optimization passes, then optional backend-targeted lowering/export | Experimental |
| 3 — Internal | low-level IR utilities | Advanced use | Subject to change |
rqm-core
↓
rqm-circuits ← canonical external/public circuit IR
↓
rqm-compiler ← this repo (internal optimization engine)
↓
rqm-qiskit / rqm-braket ← backend lowering and execution bridges
↓ (optional)
rqm-optimize
| Layer | Responsibility |
|---|---|
rqm-core |
Quaternion algebra, SU(2), Bloch sphere, spinor math |
rqm-circuits |
Canonical external/public circuit schema and IR boundary |
rqm-compiler |
Internal optimization and rewriting engine |
rqm-qiskit / rqm-braket |
Backend lowering and execution bridges |
rqm-optimize |
Optional backend-adjacent optimization and compression |
rqm-compiler does not implement quantum math and does not import any vendor SDK.
Circuit— the internal compiler circuit model used by optimization passesOperation— the internal instruction model used by compiler transforms- Gate semantics and supported gate set (compiler-internal)
- Circuit structure and composition rules
- Pass pipelines: normalization, canonicalization, gate fusion, cancellation
- Serialization helpers (
circuit_to_dict,circuit_from_dict) - Internal backend-neutral descriptor export for translation and debugging
- Compiler reports and optimization metadata (
CompilerReport)
- The canonical public/external circuit schema — belongs in
rqm-circuits - API wire format or Studio payload format — belongs in
rqm-circuits - Quaternion algebra — belongs in
rqm-core - Spinor math — belongs in
rqm-core - SU(2) or Bloch sphere math — belongs in
rqm-core - Qiskit objects or imports — belongs in
rqm-qiskit - Amazon Braket objects or imports — belongs in
rqm-braket - Any execution or simulation logic
Every gate operation inside the compiler is represented as a plain dictionary. This is the internal compiler descriptor format — useful for debugging, backend translation, and pass inspection. It is not the canonical external public circuit schema (that lives in rqm-circuits).
{
"gate": "rx", # lowercase gate name
"targets": [0], # list of target qubit indices (always present)
"controls": [], # list of control qubit indices (always present)
"params": {"angle": 1.5707963267948966} # parameter dict (always present)
}from rqm_compiler import Circuit
c = Circuit(3)
# Single-qubit gates
c.i(0); c.x(0); c.y(1); c.z(2); c.h(0); c.s(1); c.t(2)
# Parameterised single-qubit gates
c.rx(0, 1.57).ry(1, 0.78).rz(2, 3.14).phaseshift(0, 0.5)
# Two-qubit gates
c.cx(0, 1).cy(1, 2).cz(0, 2)
c.swap(0, 1).iswap(1, 2)
# Measurement
c.measure(0, key="m0")
c.measure_all() # measures all qubits with default keys
# Barrier
c.barrier()
# Export to internal compiler descriptor list
descriptors = c.to_descriptors()
# Reconstruct from a descriptor list (inverse of to_descriptors)
restored = Circuit.from_descriptors(descriptors, num_qubits=3)optimize_circuit is the recommended Tier 2 entry point. It runs the full
optimization pipeline (validate → normalize → canonicalize → flatten → to_u1q →
gate merging → cancellation) and returns an optimized circuit plus a
:class:CompilerReport. Use this as your default mental model for backend
integration.
Important: u1q is the canonical internal single-qubit optimization IR.
Named-gate lowering (e.g. rz/ry/rz) is an explicit backend-targeted stage
via lower_circuit_for_backend(...) or compile_for_backend(...).
compile_circuit is the lightweight alternative when you only need validation
and normalization without optimization.
Both functions are optional — basic circuit construction works without them.
from rqm_compiler import optimize_circuit, compile_circuit
# Preferred: optimize first, then export to backend
optimized, report = optimize_circuit(c)
print(report)
for op in optimized.to_descriptors():
translate_to_backend(op)
# Lightweight alternative: validate + normalize + export (no optimization)
compiled = compile_circuit(c)
compiled.descriptors # list of internal compiler descriptor dicts
compiled.num_qubits # int
compiled.metadata # dict with compilation metadataoptimize_circuit is proof-gated and fail-closed. It always follows:
- build a candidate optimized circuit
- run mandatory semantic verification
- commit only if verification is
VERIFIED - otherwise withhold optimization and return the original circuit unchanged
This means no successful optimization output is ever unverified.
CompilerReport records:
equivalence_status: alwaysVERIFIEDfor the returned circuitequivalence_verified: alwaysTruefor the returned circuitequivalence_guaranteed: explicit proof-gated guarantee for the returned circuitoptimization_applied:Trueonly when a verified candidate was committedfallback_reason:"verification_not_established"when optimization is withheldequivalence_report: structured payload for the committed output, plusinternal_candidate_proof_resultfor development diagnostics
Current verifier methods used internally:
U1Q_CANONICAL: exact single-qubit canonical-u1q comparisonUNITARY_NUMERICAL: dense unitary comparison up to global phase for supported small circuitsGATEWISE_IDENTITY: exact descriptor identity check for fully-resolved circuits
Important semantics:
- Only verified candidates are committed as optimized output.
- If proof fails, is unsupported, or errors, optimization is not committed.
- Unsupported proof coverage causes optimization refusal/fallback, not uncertain output.
Backend repos should prefer optimize_circuit because it runs gate merging and
cancellation before translation — circuits with redundant or adjacent single-qubit
gates will be cheaper to execute after optimization. Verify the trade-off for
your specific circuit patterns.
Circuit.from_descriptors(descriptors, num_qubits) is the inverse of
to_descriptors(). It reconstructs a compiler Circuit from the internal
descriptor format — useful for debugging, reproducibility, backend roundtrips,
and tests. This is not the canonical external public IR boundary (which is
owned by rqm-circuits).
from rqm_compiler import Circuit, optimize_circuit
c = Circuit(2)
c.h(0).cx(0, 1).measure_all()
# Optimize and capture the internal compiler descriptor IR
optimized, report = optimize_circuit(c)
descriptors = optimized.to_descriptors()
# Later: reconstruct a Circuit from those descriptors
restored = Circuit.from_descriptors(descriptors, num_qubits=optimized.num_qubits)
assert restored.to_descriptors() == descriptorsfrom rqm_compiler.io import circuit_to_dict, circuit_from_dict
data = circuit_to_dict(c) # serialize to JSON-compatible dict
restored = circuit_from_dict(data) # reconstruct Circuit from dict| Category | Gates |
|---|---|
| Single-qubit | i x y z h s t |
| Parameterised single-qubit | rx ry rz phaseshift (param: angle) |
| Two-qubit | cx cy cz swap iswap |
| Other | measure barrier |
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytestSee AGENTS.md for the full list of contributor boundary rules.