compactq 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. compactq-0.1.0/LICENSE +21 -0
  2. compactq-0.1.0/PKG-INFO +569 -0
  3. compactq-0.1.0/README.md +539 -0
  4. compactq-0.1.0/compactq/__init__.py +62 -0
  5. compactq-0.1.0/compactq/__main__.py +210 -0
  6. compactq-0.1.0/compactq/adapters.py +107 -0
  7. compactq-0.1.0/compactq/approximate.py +27 -0
  8. compactq-0.1.0/compactq/bench.py +116 -0
  9. compactq-0.1.0/compactq/benchmarks.py +110 -0
  10. compactq-0.1.0/compactq/cdr.py +155 -0
  11. compactq-0.1.0/compactq/circuit.py +99 -0
  12. compactq-0.1.0/compactq/cirq_bridge.py +37 -0
  13. compactq-0.1.0/compactq/clifford.py +448 -0
  14. compactq-0.1.0/compactq/cliffordt.py +253 -0
  15. compactq-0.1.0/compactq/cp_pass.py +147 -0
  16. compactq-0.1.0/compactq/equivalence.py +205 -0
  17. compactq-0.1.0/compactq/errors.py +15 -0
  18. compactq-0.1.0/compactq/hardware.py +507 -0
  19. compactq-0.1.0/compactq/interfaces.py +49 -0
  20. compactq-0.1.0/compactq/io_qasm.py +425 -0
  21. compactq-0.1.0/compactq/io_qasm3.py +17 -0
  22. compactq-0.1.0/compactq/kak.py +831 -0
  23. compactq-0.1.0/compactq/linalg.py +253 -0
  24. compactq-0.1.0/compactq/mcx.py +84 -0
  25. compactq-0.1.0/compactq/metrics.py +106 -0
  26. compactq-0.1.0/compactq/mitigate.py +158 -0
  27. compactq-0.1.0/compactq/native.py +342 -0
  28. compactq-0.1.0/compactq/noise.py +162 -0
  29. compactq-0.1.0/compactq/optimize.py +125 -0
  30. compactq-0.1.0/compactq/parity.py +234 -0
  31. compactq-0.1.0/compactq/permkak.py +97 -0
  32. compactq-0.1.0/compactq/plugins/__init__.py +1 -0
  33. compactq-0.1.0/compactq/plugins/qiskit_plugin.py +108 -0
  34. compactq-0.1.0/compactq/qiskit_bridge.py +105 -0
  35. compactq-0.1.0/compactq/report.py +103 -0
  36. compactq-0.1.0/compactq/resources.py +100 -0
  37. compactq-0.1.0/compactq/search.py +199 -0
  38. compactq-0.1.0/compactq/shadows.py +92 -0
  39. compactq-0.1.0/compactq/simulate.py +256 -0
  40. compactq-0.1.0/compactq/solvers.py +111 -0
  41. compactq-0.1.0/compactq/stabilizer.py +246 -0
  42. compactq-0.1.0/compactq/stabsim.py +287 -0
  43. compactq-0.1.0/compactq/suppress.py +587 -0
  44. compactq-0.1.0/compactq/symbolic.py +187 -0
  45. compactq-0.1.0/compactq/target.py +254 -0
  46. compactq-0.1.0/compactq/templates.py +91 -0
  47. compactq-0.1.0/compactq/tests/__init__.py +0 -0
  48. compactq-0.1.0/compactq/tests/conftest.py +3 -0
  49. compactq-0.1.0/compactq/tests/test_compactq.py +34 -0
  50. compactq-0.1.0/compactq/transforms.py +274 -0
  51. compactq-0.1.0/compactq/verify_large.py +135 -0
  52. compactq-0.1.0/compactq/winmerge.py +124 -0
  53. compactq-0.1.0/compactq/zne.py +180 -0
  54. compactq-0.1.0/compactq.egg-info/PKG-INFO +569 -0
  55. compactq-0.1.0/compactq.egg-info/SOURCES.txt +59 -0
  56. compactq-0.1.0/compactq.egg-info/dependency_links.txt +1 -0
  57. compactq-0.1.0/compactq.egg-info/entry_points.txt +4 -0
  58. compactq-0.1.0/compactq.egg-info/requires.txt +6 -0
  59. compactq-0.1.0/compactq.egg-info/top_level.txt +1 -0
  60. compactq-0.1.0/pyproject.toml +44 -0
  61. compactq-0.1.0/setup.cfg +4 -0
compactq-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Q-PROOF contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,569 @@
1
+ Metadata-Version: 2.4
2
+ Name: compactq
3
+ Version: 0.1.0
4
+ Summary: Q-PROOF Compact: the verified quantum circuit optimizer. Smaller circuits, proven. Error suppression included.
5
+ Author: Q-PROOF contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Q-PROOF/Compact
8
+ Project-URL: Repository, https://github.com/Q-PROOF/Compact
9
+ Project-URL: Issues, https://github.com/Q-PROOF/Compact/issues
10
+ Project-URL: Changelog, https://github.com/Q-PROOF/Compact/blob/main/CHANGELOG.md
11
+ Keywords: quantum,compiler,optimizer,transpiler,circuit,qiskit,compact,verified,error-suppression,dynamical-decoupling,pauli-twirling,noise
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Physics
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Provides-Extra: bench
26
+ Requires-Dist: qiskit>=1.0; extra == "bench"
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # Q-PROOF Compact
32
+
33
+ **The verified quantum circuit optimizer.** Smaller circuits, proven. Compact takes a quantum circuit and returns an equivalent one that is smaller and shallower — with a machine-checked proof attached to every answer.
34
+
35
+ ```python
36
+ import compactq
37
+ from compactq.benchmarks import qft
38
+
39
+ opt = compactq.optimize_search(qft(4))
40
+ print(opt.stats())
41
+ ```
42
+
43
+ `pip install compactq` — no dependencies, no account, no cloud. Pure Python ≥ 3.9.
44
+ (From source: `pip install git+https://github.com/Q-PROOF/Compact.git`.)
45
+
46
+ ## Why
47
+
48
+ Every gate you remove from a quantum circuit removes noise. Compact takes a circuit and
49
+ returns an **equivalent** one that is smaller (fewer gates), shallower (lower depth),
50
+ with priority on cutting 2-qubit gates — the dominant error source on today's hardware.
51
+
52
+ ## Correctness model (the part that matters)
53
+
54
+ - Every rewrite is **exact**: the unitary is preserved up to global phase.
55
+ - For circuits ≤ 8 qubits (6 without the optional native kernel), `optimize_search()`
56
+ **proves** equivalence via full-unitary comparison before returning; on any numerical
57
+ doubt it returns your circuit unchanged. (`verify=False` skips the proof for large
58
+ circuits — and is itself fuzzed against a Qiskit referee up to 10 qubits.)
59
+ - The KAK/Weyl re-synthesiser is cross-validated against Qiskit's Rust implementation
60
+ (Weyl coordinates agree to ~1e-15 on randomized SU(4)s) and every re-synthesized
61
+ block is re-verified against its own 4×4 unitary before it can replace anything.
62
+ - Clifford blocks are re-synthesized with **tableau proofs**, exact at any qubit count.
63
+ - The test suite (76 test functions; `python tests/run_tests.py`) includes property tests over thousands of random circuits
64
+ and a regression suite for the classic optimizer bugs (gate-order reversals,
65
+ reversed-CX "cancellations", Euler-angle wrapping, ZZ-identity sign errors).
66
+ `scripts/gauntlet.py` adds a 1,018-check end-to-end gauntlet: 61 realistic algorithm
67
+ families × every public entry point, QASMBench through compactq's own importer, >8q
68
+ no-verify soundness and CLI/bridge/round-trip checks — all refereed by Qiskit's
69
+ `Operator`, never by compactq's own math.
70
+
71
+ ## What's inside
72
+
73
+ - **Peephole folding** — maximal 1-qubit runs resynthesized to ≤3 canonical gates
74
+ (named-Clifford recognition, single-RX/RY recovery, exact H·P / P·H two-gate forms,
75
+ RZ-RY-RZ Euler), with a final single-`u3` fold for gate-count polish.
76
+ - **Commutation engine** — self-inverse CX/CZ cancellation across provably-commuting
77
+ gates, X-on-target / diagonal-on-control slides, SWAP templates, generalized
78
+ diagonal sliding, cross-pair commutative window merging.
79
+ - **CP engine** — `CX·RZ_t(θ)·CX = RZ_c(θ)·RZ_t(θ)·CP(−2θ)`: exact ZZ-phase
80
+ extraction that halves the CX count of QAOA/QFT/PEA-style phase ladders; adjacent
81
+ CP merging; phase-polynomial re-synthesis of diagonal cores.
82
+ - **Pure-Python KAK/Weyl synthesis** (`compactq/kak.py`) — the numerically-stable
83
+ simultaneous-diagonalization algorithm (Cross et al., arXiv:1811.12926 App. B):
84
+ real-symmetric Jacobi eigensolver of Re/Im magic-basis parts, Weyl-chamber
85
+ canonicalization, and minimal-CX circuit templates (0/1/2/3 CX by exact
86
+ fidelity test). No numpy, no qiskit, no pytket needed in the core.
87
+ - **Clifford stabilizer tableaux** (`compactq/stabilizer.py`) — Aaronson-Gottesman
88
+ CHP with phase-exact Pauli conjugation (single-qubit gates conjugated
89
+ numerically, so a wrong sign convention cannot ship silently) and AG block
90
+ resynthesis with GF(2) sign correction. `is_clifford` and `clifford_equal`
91
+ give exact Clifford equality at any qubit count without building 2ⁿ unitaries.
92
+ - **Approximate mode** (`compactq.approximate`, `compactq.target`) — 2q blocks re-synthesized
93
+ into cheaper CX classes with *measured* per-block fidelity guarantees; hardware-aware
94
+ `Target` objective (per-pair CX fidelities, CX-direction flipping) and greedy
95
+ fidelity-budget allocation. Reported fidelities include the approximation cost.
96
+ - **Hardware-aware routing** (`compactq/hardware.py`) — SABRE-lite SWAP insertion with
97
+ error-weighted look-ahead, optional permutation restore, `rz-sx-x` 1q translation.
98
+ - **Multi-controlled gates** — `mcx`/`mcp` expanded via parity networks; the Qiskit
99
+ bridge boundary-decomposes anything else a `QuantumCircuit` may carry (`mcphase`,
100
+ `ccx`, `ecr`, `iswap`, `cu`, `rxx`, ...) loss-free into the supported basis.
101
+ - **Verification net** — full-unitary fidelity proofs for ≤8-qubit circuits.
102
+ - **Optional Rust kernels** (`native/`) — a PyO3 wheel (`compactq-native`, abi3
103
+ stable ABI, Python ≥3.9) that accelerates the KAK hot path (block unitaries,
104
+ determinants) and raises the exact-proof ceiling to 8 qubits (`sim_unitary`).
105
+ Windows wheels ship with each release; other platforms build from source with
106
+ `maturin` (see Development). compactq auto-detects the kernel and silently
107
+ falls back to the pure-Python path — the zero-dependency contract never changes.
108
+
109
+ ## How Compact competes
110
+
111
+ Three axes, all measured on identical inputs (QASMBench unitary cores, level-0
112
+ normalized, same basis, 2026-09-08 run unless noted):
113
+
114
+ **1. Optimization quality** — win-or-tie on 2-qubit count vs Qiskit L3 on 30/32
115
+ QASMBench small circuits (11 wins / 19 ties / 2 losses). One loss
116
+ (`basis_test_n4`, 12 vs "6") is an accounting artifact: Qiskit L3 *elides* 2 SWAP
117
+ gates into its layout metadata instead of the circuit — reified, they cost 6
118
+ CX-equivalents, i.e. parity with compactq's 12; the other (`basis_trotter_n4`,
119
+ 240 vs 179) is a genuine open case, on the roadmap. Vs pytket
120
+ `FullPeepholeOptimise`, see axis 2: its headline 2q
121
+ numbers on small kernels come from invalid outputs. On freshly generated
122
+ **MQT Bench** algorithm circuits (44 circuits, every output refereed, table
123
+ below) compactq **wins 25 / ties 19 / loses 0** vs Qiskit L3 — QAOA 2q cut in
124
+ half at every size (8→4, 28→14, 56→28), QFT 14→8, QPE 9→5, Grover
125
+ 52→44 — and **25 / 19 / 0** vs Cirq's `CZTargetGateset` optimizer. The
126
+ v1.3 CX-phase rewrite (matched CX pairs around folded T/phase runs collapse
127
+ to CP) closes every previously-lost 2q account: adder_n10 65→**57**,
128
+ adder_n4 10→**7**, toffoli 6→**5**, cdkm adders **15/29** vs pytket's
129
+ 16/31, Grover −16%.
130
+
131
+ **2. Precision** — Compact *proves* every output before returning (full-unitary
132
+ fidelity proof ≤ 8q, tableau proofs for Clifford blocks at any size; it returns
133
+ your input unchanged rather than ship an unprovable result).
134
+ An independent referee (Qiskit `Operator`, |Tr(A†B)|/d) over 29 QASMBench circuits:
135
+
136
+ | tool | inequivalent outputs | what the user must do to be safe |
137
+ |---|---|---|
138
+ | **Compact** | **0 / 29** (proof attached in-product) | nothing |
139
+ | Qiskit 2.5 L3 | 1 / 29 *as shipped*: `basis_trotter_n4` returns fid 0.25 because 2 SWAPs sit in `qc.layout` metadata, not the circuit | inspect `qc.layout` and re-apply elided permutations |
140
+ | pytket `FullPeepholeOptimise()` (default) | **6 / 30 wrong circuits** (fresh 2.18.1 referee: basis_test_n4 fid 0.50, grover_n2 0.50, hs4_n4 0.25, iswap_n2 0.50, qec_en_n5 0.25, sat_n7 0.016); `replace_implicit_wire_swaps()` does **not** repair them | run in `allow_swaps=False` mode — but 2.18.1's safe mode is itself inequivalent on 2/30 (basis_trotter_n4, sat_n7), and its valid outputs still never beat compactq (9 / 19 / 0) |
141
+ | pytket safe mode | 2 / 30 (basis_trotter_n4 fid 0.5, sat_n7 fid 0.016) | re-referee before trusting |
142
+
143
+ **3. Latency** — the honest metric is the *same job*: an optimized circuit you can
144
+ trust. compactq's price includes the proof; competitors need an external
145
+ `Operator`-fidelity check afterwards (which is exactly what caught the failures
146
+ above).
147
+
148
+ | same job (optimize + verify) | compactq (proof included) | Qiskit L3 raw | Qiskit + verify | compactq wins | pytket + verify (compactq wins) |
149
+ |---|---|---|---|---|---|
150
+ | QASMBench, 29 circuits | **1.86 s** | 0.52 s | 0.88 s | **18/29** | 11.0 s, **29/29** |
151
+ | MQT Bench, 44 circuits | **4.88 s** | 0.85 s | 1.97 s | 22/44 | — |
152
+
153
+ (timings from the 2026-09-08 instrumentation run; the correctness side was
154
+ re-verified fresh on 2026-09-16/17 — the full gauntlet passes 1018/1018 on the
155
+ current code, and the referee counts above are from that run.)
156
+
157
+ compactq wins the same-job race on the **majority of circuits** (18/29 QASMBench,
158
+ 22/44 MQT — tally per the table above) and is always 4–6x faster than pytket;
159
+ Qiskit's Rust pass engine keeps the raw-speed crown, especially on large circuits
160
+ (closing that gap needs compactq's pass engine itself in Rust — on the roadmap).
161
+ End-to-end optimizer+prover throughput doubled across the prototyping phase: the
162
+ 1,018-check gauntlet runs 150 s → 75 s and the trotter6 search 4.9x (1.18 s →
163
+ 0.24 s), via native-kernel verification at all qubit counts, a value-keyed
164
+ unitary memo, fused 1q-matrix comparison, memoized gate matrices, and the Rust
165
+ `trace2` fidelity kernel.
166
+
167
+ Competitor landscape (measured columns from the runs above; others qualitative):
168
+
169
+ | tool | scope | output verification | 2q optimization | notes |
170
+ |---|---|---|---|---|
171
+ | **Compact 0.1 (Q-PROOF)** | logical optimization, exact + approximate | **yes — in-product proof** | **best measured** (30/32 win-or-tie QASMBench; 25/19/0 vs Qiskit and Cirq on MQT; 9/19/0 vs pytket-2.18 safe mode) | same-job latency won on the majority of circuits; zero-dependency core, optional Rust |
172
+ | Qiskit 2.5 transpiler (L3) | full transpilation stack (layout/routing/noise-adaptive) | none | strong; parity with compactq once permutations are reified | Rust-fast, huge ecosystem |
173
+ | pytket 2.18 (`FullPeepholeOptimise`) | logical optimization | none — **6/30 wrong by default** (fresh referee; safe mode now also 2/30 wrong: basis_trotter_n4, sat_n7) | on its 24 valid default-mode outputs: compactq wins 8 / ties 15 / loses 1 (basis_trotter_n4); safe mode: compactq **9 / 19 / 0** | the SWAP-elision pitfall persists in 2.18.1 |
174
+ | Cirq 1.7 (`optimize_for_target_gateset`) | construction + target-gateset optimization | none — but its optimizer is exact on our whole MQT run | weak: 23 losses / 0 wins vs compactq on MQT; grows some circuits | fast (tens of ms) |
175
+ | staq (softwareqinc) | synthesis/optimization toolchain | n/a | n/a | **not measurable in this environment**: no PyPI distribution (the PyPI `staq` package is an unrelated C decompiler) and building it needs a C++17 toolchain that is absent here |
176
+ | MQT Bench (mqt-bench, ALG level) | benchmark *generator* (44 circuits run here) | — | — | integrated as a first-class suite: `python scripts/mqtbench_run.py` |
177
+
178
+ **DD sequences, every surface** — suppression goes deeper and ships everywhere:
179
+ a dynamical-decoupling **sequence family** (`DD_SEQUENCES`: xy4, xy8,
180
+ xzx, pdd4) with `auto` selection by window length (`dd_sequence=`
181
+ through `suppress_plan`/`suppress_execute`, sequence gate
182
+ `--dd-sequences`); the pipeline is reachable from **every surface** —
183
+ `compactq in.qasm --suppress [--noise noise.json] [--report
184
+ report.json] [--json]` on the CLI, and `make_suppression_pass()` /
185
+ `suppress_qiskit()` in the qiskit plugin (calibration ingestion from a
186
+ BackendV2, coupling-map aware, proof-verified variant 0).
187
+
188
+ **End-to-end pipeline** — noise-aware layout +
189
+ SABRE-lite routing wired into `suppress_plan` (device-space mapping with
190
+ per-edge calibration sight), a `SuppressionReport` artifact (per-stage
191
+ gate/depth/proof-level records + measured suppression factor), MLE
192
+ measurement mitigation (Richardson-Lucy EM - always a physical
193
+ distribution, beats clipped inversion 3-5x on injected confusion), thin
194
+ execution adapters (`compactq.adapters.qiskit_runtime` /
195
+ `braket_device`), model-gated twirling (`coherent_fraction`) with
196
+ portfolio `twirl_fraction`, an optimization regression gate
197
+ (`scripts/bench_gate.py`), a CHP stabilizer scale simulator
198
+ (`compactq.stabsim`, n~60; Y-convention audit discharged by the fuzz
199
+ suite) with a gate-checked n=16..24 scale benchmark
200
+ (`scripts/scale_bench.py`), and exact zero-noise extrapolation
201
+ (`compactq.zne` - provable identity folding + Richardson/poly fits).
202
+
203
+ ## Error suppression — the open stack, one call
204
+
205
+ Fire Opal (Q-CTRL) sells automated error suppression as a closed cloud
206
+ service: transpilation, fidelity-aware layout, dynamical decoupling, Pauli
207
+ twirling, measurement mitigation — one function call, no knobs, results
208
+ that cannot be audited. Compact ships the same technique stack as an open,
209
+ zero-dependency, **exactly provable** library that runs locally against
210
+ any noise model:
211
+
212
+ | Fire Opal | Compact suppression |
213
+ |---|---|
214
+ | closed cloud, paid usage | open source, free, local — data never leaves the machine |
215
+ | transformed circuits unauditable | every pass exact up to global phase, proof-net verified before use |
216
+ | only on their supported backends | any `NoiseModel` (plain dict, or live IBM calibration loading) |
217
+ | black-box pipeline | automated default + every layer available standalone |
218
+ | suppression only on their stack | composes with any compiler — works on qiskit-O3 output too |
219
+
220
+ ```python
221
+ from compactq import Circuit, Gate, suppress_execute, default_model
222
+
223
+ circ = Circuit(4, [Gate("h", (), (0,))] + [Gate("cx", (), (j, j+1)) for j in range(3)])
224
+ noise = default_model(4) # or NoiseModel.from_qiskit_backend(backend)
225
+ result = suppress_execute(circ, noise) # plan -> run -> mitigate
226
+ best = max(result["probabilities"], key=result["probabilities"].get)
227
+ ```
228
+
229
+ Pipeline (fixed order, each layer exact and gated): optimize → expand
230
+ untwirlable CP entanglers → K Pauli-twirled variants → dynamical decoupling
231
+ placed on each variant's own schedule → tensored readout mitigation.
232
+ DD is **benefit-gated**: a window is decoupled only when the model's
233
+ refocusable noise (quasi-static drift + dephasing) beats 3x the pulse
234
+ overhead, so the pass can never be a net loss. Every variant is proven
235
+ equivalent to your input before it is used.
236
+
237
+ **Measured** (density-matrix noise simulation — coherent overrotation per
238
+ 2q gate with per-site axes, gate depolarizing, T1/T2 with ASAP scheduling,
239
+ quasi-static drift, readout confusion; fixed seeds; reproducible with
240
+ `python scripts/suppress_bench.py` and `python scripts/head_to_head.py`):
241
+
242
+ - full pipeline vs raw execution: wins in **every** scenario — success
243
+ probability x1.00–1.01 (coherent-dominated), x1.04–**2.72** (decoherence),
244
+ x1.17–1.31 (readout-dominated), x1.06–1.13 (combined)
245
+ - head-to-head (`head_to_head_results.json`): raw vs qiskit-O3 vs
246
+ qiskit-O3+suppression vs compact-full — mean success probability
247
+ coherent **0.825** (qiskit-O3 0.822, raw 0.808), decoherence **0.660**
248
+ (0.431, 0.418), combined **0.766** (0.688, 0.677); single best cell
249
+ BV n=6 decoherence **0.729 vs 0.138** (5.3x). The suppression stack
250
+ also lifts qiskit-O3 output when composed onto it.
251
+ - one-cell honesty note: on coherent-dominated QAOA n=4, bare qiskit-O3
252
+ beats *every* suppressed pipeline (including qiskit-O3+suppression) —
253
+ randomized compiling trades coherent-error cancellation for stochastic
254
+ robustness; the aggregate still favors the pipeline.
255
+
256
+ The zero-dependency trajectory simulator (`compactq.simulate_counts`)
257
+ reproduces the same physics for n <= 14 without numpy, so the whole
258
+ pipeline runs — and is tested — anywhere Python runs.
259
+
260
+ **Honesty line:** Fire Opal's headline numbers come from real hardware;
261
+ ours are simulator-based by construction (the techniques are the published
262
+ ones — Mundada et al. randomized compiling, XY4 decoupling, tensored
263
+ readout inversion). What we add is what no closed service can offer:
264
+ per-layer exactness proofs, benefit gating with a no-net-loss argument,
265
+ and a protocol anyone can re-run.
266
+
267
+ All numbers below are from a single re-run (2026-09-16, Python 3.11.9, qiskit 2.5.2,
268
+ pytket 2.18.1, Windows 11 x64, compactq 0.1.0 + native kernels 0.1.0) and are
269
+ reproducible with the commands shown. `gates / 2q / depth`.
270
+
271
+ Synthetic suite (`python -m compactq.bench`; same input QASM, same basis, fixed seeds):
272
+
273
+ | circuit | raw | Compact | qiskit L3 | 2q gain |
274
+ |---|---|---|---|---|
275
+ | ghz-5 | 5 / 4 / 5 | 5 / 4 / 5 | 5 / 4 / 5 | -0% |
276
+ | qft-3 | 18 / 6 / 14 | **14 / 6 / 11** | 14 / 6 / 11 | -0% |
277
+ | qft-4 | 34 / 12 / 22 | **25 / 12 / 17** | 25 / 12 / 17 | -0% |
278
+ | clifford-ladder-4 | 12 / 7 / 8 | 12 / 7 / 8 | 12 / 7 / 8 | -0% |
279
+ | clifford-ladder-5 | 15 / 8 / 13 | **13 / 8 / 11** | 13 / 8 / 11 | -0% |
280
+ | brickwork-4x4 | 44 / 12 / 16 | 40 / 12 / 17 | 40 / 12 / 16 | -0% |
281
+ | random-4q-40 | 40 / 18 / 24 | **37 / 18 / 21** | 40 / 22 / 27 | **-18%** |
282
+ | random-5q-60 | 60 / 22 / 37 | **49 / 22 / 30** | 62 / 28 / 37 | **-21%** |
283
+
284
+ Real circuits — QASMBench **small** suite (`python scripts/realbench.py`; unitary
285
+ cores only — circuits with classical control flow or mid-circuit measurement are out
286
+ of scope for a unitary optimizer and are skipped with a stated reason; 31 of 42 ran).
287
+ Every compactq row ≤ 8q is unitary-verified before being reported (0 inequivalent
288
+ outputs, refereed by `scripts/bench_json.py`); Qiskit L3 and pytket are unverified.
289
+ QASMBench assets are vendored in-tree (`third_party/QASMBench` — the small suite
290
+ plus the medium/large circuits tabulated below, pinned at pnnl/QASMBench `357b942`,
291
+ attribution in its LICENSE/NOTICE), so every number here is reproducible from a
292
+ fresh clone with no submodule step.
293
+
294
+ | circuit | Compact | qiskit L3 | pytket FullPeephole |
295
+ |---|---|---|---|
296
+ | adder_n10 | **110 / 57 / 95** | 137 / 65 / 99 | 165 / 61† / 118 |
297
+ | adder_n4 | **16 / 7 / 9** | 23 / 10 / 11 | 25 / 10 / 14 |
298
+ | basis_change_n3 | **34 / 10 / 22** | 49 / 10 / 28 | 79 / 10 / 50 |
299
+ | basis_test_n4 | 34 / 12 / 15 | 34 / 6¹ / 12 | 42 / 5† / 16 |
300
+ | basis_trotter_n4 | 773 / 240 / 352 | 794 / 179 / 361 | 969 / 159 / 419 |
301
+ | bell_n4 | **18 / 5 / 7** | 27 / 5 / 11 | 29 / 5 / 12 |
302
+ | cat_state_n4 | 4 / 3 / 4 | 4 / 3 / 4 | 6 / 3 / 6 |
303
+ | deutsch_n2 | 4 / 1 / 3 | 4 / 1 / 3 | 9 / 1 / 6 |
304
+ | dnn_n2 | **12 / 3 / 8** | 20 / 3 / 13 | 29 / 3 / 17 |
305
+ | dnn_n8 | **216 / 64 / 37** | 345 / 64 / 60 | 464 / 64 / 75 |
306
+ | error_correctiond3_n5 | **23 / 8 / 13** | 91 / 35 / 65 | 40 / 9 / 20 |
307
+ | fredkin_n3 | 19 / 8 / 11 | 19 / 8 / 11 | 22 / 8 / 13 |
308
+ | grover_n2 | 7 / 2 / 5 | 7 / 2 / 5 | 9 / 1† / 7 |
309
+ | hhl_n7 | **191 / 72 / 128** | 254 / 92 / 168 | 421 / 92 / 310 |
310
+ | hs4_n4 | 12 / 4 / 5 | 12 / 4 / 5 | 14 / 2† / 7 |
311
+ | ising_n10 | **166 / 49 / 29** | 260 / 90 / 46 | 370 / 90 / 58 |
312
+ | iswap_n2 | **7 / 2 / 5** | 8 / 2 / 6 | 9 / 1† / 7 |
313
+ | linearsolver_n3 | **11 / 4 / 9** | 17 / 4 / 12 | 25 / 4 / 19 |
314
+ | lpn_n5 | 7 / 2 / 4 | 7 / 2 / 4 | 15 / 2 / 8 |
315
+ | pea_n5 | **34 / 10 / 21** | 51 / 17 / 32 | 62 / 17 / 41 |
316
+ | qaoa_n6 | **114 / 36 / 47** | 166 / 36 / 63 | 197 / 36 / 83 |
317
+ | qec_en_n5 | 23 / 10 / 15 | 23 / 10 / 15 | 24 / 8† / 14 |
318
+ | qft_n4 | **20 / 6 / 10** | 34 / 12 / 20 | 39 / 12 / 23 |
319
+ | qrng_n4 | 4 / 0 / 1 | 4 / 0 / 1 | 12 / 0 / 3 |
320
+ | quantumwalks_n2 | **8 / 2 / 5** | 20 / 3 / 13 | 36 / 3 / 22 |
321
+ | sat_n7 | **125 / 52 / 71** | 158 / 60 / 86 | 193 / 60 / 107 |
322
+ | simon_n6 | **30 / 12 / 22** | 43 / 14 / 27 | 58 / 14 / 37 |
323
+ | teleportation_n3 | **5 / 2 / 4** | 6 / 2 / 4 | 12 / 2 / 8 |
324
+ | toffoli_n3 | **14 / 5 / 10** | 18 / 6 / 12 | 21 / 6 / 14 |
325
+ | variational_n4 | **29 / 8 / 14** | 44 / 8 / 18 | 51 / 8 / 24 |
326
+ | vqe_n4 | **25 / 9 / 11** | 46 / 9 / 18 | 75 / 9 / 23 |
327
+ | wstate_n3 | **18 / 6 / 12** | 22 / 6 / 15 | 30 / 6 / 21 |
328
+
329
+ † pytket 2.18.1's default-mode output fails unitary verification on this circuit
330
+ (fresh referee, `scripts/referee_pytket.py`: 6 of 30 ≤8q outputs inequivalent —
331
+ basis_test_n4 fid 0.50, grover_n2 0.50, hs4_n4 0.25, iswap_n2 0.50, qec_en_n5 0.25,
332
+ sat_n7 0.016; adder_n10 exceeds the 8q referee ceiling) — those counts are not
333
+ comparable. ¹ Qiskit L3 elides 2 SWAPs into `qc.layout` metadata here; reified they
334
+ cost 6 CX-equivalents — parity with compactq's 12.
335
+
336
+ Tallies vs Qiskit L3 (32 comparable rows from `python scripts/bench_json.py`, same
337
+ run): **2q win-or-tie 30/32** (11 wins / 19 ties / 2 losses), total-gate win **23 / tie
338
+ 9 / lose 0**, depth win **22 / tie 9 / lose 1**. Zero compactq outputs flagged
339
+ INEQUIVALENT by the referee; Qiskit L3 is referee-flagged on basis_test_n4 (the
340
+ SWAP-elision above). The two 2q accounts not won: basis_test_n4 (12 vs 6 raw —
341
+ accounting parity once Qiskit's 2 elided SWAPs are reified) and basis_trotter_n4
342
+ (240 vs 179 — a pi/4-quantized Clifford+T ring whose optimization needs a
343
+ CliffordSimp-class fragment-resynthesis pass; on the roadmap).
344
+
345
+ Vs **pytket 2.18.1** (fresh referee, same protocol, `scripts/referee_pytket.py`):
346
+ default mode is inequivalent on **6 of 30** refereed circuits; of its 24 *valid*
347
+ outputs compactq wins the 2q count on 8 / ties 15 / loses 1 (basis_trotter_n4 —
348
+ the roadmap item above). In pytket's **safe** (`allow_swaps=False`) mode — now
349
+ itself inequivalent on 2 of 30 (basis_trotter_n4 fid 0.5, sat_n7 fid 0.016) — the
350
+ valid-output tally is **compactq 9 / tie 19 / lose 0**: zero valid 2q losses.
351
+
352
+ QASMBench **medium** (≤ 12 qubits; `python scripts/realbench.py --size medium
353
+ --max-qubits 12` — most medium files are ≥ 14q or carry classical control flow):
354
+
355
+ | circuit | Compact | qiskit L3 | pytket |
356
+ |---|---|---|---|
357
+ | sat_n11 | **486 / 212 / 355** | 599 / 252 / 403 | 713 / 250 / 507 |
358
+
359
+ (sat_n11 improved again this run: 212 2q vs the 252 of the 2026-09-08 run and a
360
+ 252-vs-252 tie before that — the cross-pair/KAK pipeline keeps finding more.)
361
+
362
+ QASMBench **large** (≤ 32 qubits; `python scripts/realbench.py --size large
363
+ --max-qubits 32`; > 8q runs the no-verify path, soundness of which is fuzzed
364
+ against a Qiskit referee up to 10 qubits in the gauntlet):
365
+
366
+ | circuit | Compact | qiskit L3 | pytket |
367
+ |---|---|---|---|
368
+ | adder_n28 | **328 / 171 / 185** | 412 / 195 / 189 | 526 / 183 / 231 |
369
+ | bv_n30 | **55 / 18 / 20** | 79 / 18 / 20 | 197 / 18 / 24 |
370
+ | knn_n31 | **226 / 90 / 96** | 290 / 105 / 125 | 365 / 105 / 129 |
371
+ | qft_n29 | **805 / 370 / 85** | 1261 / 602 / 194 | 1699 / 806 / 197 |
372
+
373
+ (cc_n32 and vqe_uccsd_n28 skipped: classical control flow / non-standard QASM.
374
+ adder_n28 flipped from a 2026-09-08 loss (422/195 vs 412/195) to a clear win
375
+ (328/171 vs 412/195) with the current pass pipeline.)
376
+
377
+ MQT Bench — freshly generated algorithm-level circuits
378
+ (`python scripts/mqtbench_run.py`; mqt-bench, 44 circuits run, every tool's output
379
+ refereed at ≤8q; all four tools exact unless marked ‡). gates / 2q / depth:
380
+
381
+ | circuit | Compact | qiskit L3 | pytket FullPeephole | cirq CZTargetGateset |
382
+ |---|---|---|---|---|
383
+ | ghz_n4 | 4 / 3 / 4 | 4 / 3 / 4 | 6 / 3 / 6 | 11 / 3 / 7 |
384
+ | ghz_n6 | 6 / 5 / 6 | 6 / 5 / 6 | 8 / 5 / 8 | 17 / 5 / 11 |
385
+ | ghz_n8 | 8 / 7 / 8 | 8 / 7 / 8 | 10 / 7 / 10 | 23 / 7 / 15 |
386
+ | wstate_n4 | 13 / 6 / 8 | 13 / 6 / 8 | 25 / 6 / 14 | 21 / 6 / 11 |
387
+ | wstate_n6 | 21 / 10 / 12 | 21 / 10 / 12 | 41 / 10 / 20 | 35 / 10 / 17 |
388
+ | graphstate_n4 | 8 / 4 / 4 | 8 / 4 / 4 | 16 / 4 / 9 | 8 / 4 / 4 |
389
+ | graphstate_n6 | 12 / 6 / 4 | 12 / 6 / 4 | 24 / 6 / 12 | 12 / 6 / 4 |
390
+ | graphstate_n8 | 16 / 8 / 6 | 16 / 8 / 6 | 32 / 8 / 17 | 16 / 8 / 6 |
391
+ | qaoa_n4 | **20 / 4 / 10** | 23 / 8 / 15 | 50 / 8 / 33 | 25 / 8 / 17 |
392
+ | qaoa_n6 | **54 / 14 / 16** | 60 / 28 / 24 | 114 / 28 / 41 | 79 / 28 / 30 |
393
+ | qaoa_n8 | **100 / 28 / 36** | 108 / 56 / 54 | 182 / 56 / 66 | 163 / 56 / 70 |
394
+ | qft_n4 | **21 / 8 / 11** | 31 / 12 / 21 | 33 / 12 / 23 ‡ | 53 / 18 / 28 |
395
+ | qft_n6 | **44 / 18 / 17** | 71 / 30 / 35 | 73 / 30 / 37 ‡ | 110 / 39 / 45 |
396
+ | qft_n8 | **75 / 32 / 23** | 127 / 56 / 49 | 129 / 56 / 51 ‡ | 187 / 68 / 62 |
397
+ | qftentangled_n4 | **25 / 11 / 15** | 35 / 15 / 23 | 38 / 15 / 26 ‡ | 63 / 21 / 32 |
398
+ | qftentangled_n6 | **50 / 23 / 21** | 77 / 35 / 37 | 80 / 35 / 40 ‡ | 126 / 44 / 49 |
399
+ | vqe_real_amp_n4 | 25 / 9 / 11 | 25 / 9 / 11 | 73 / 9 / 26 | 33 / 9 / 15 |
400
+ | vqe_real_amp_n6 | 39 / 15 / 13 | 39 / 15 / 13 | 111 / 15 / 30 | 53 / 15 / 19 |
401
+ | vqe_real_amp_n8 | 53 / 21 / 15 | 53 / 21 / 15 | 149 / 21 / 34 | 73 / 21 / 23 |
402
+ | vqe_two_local_n4 | 34 / 18 / 17 | 34 / 18 / 17 | 82 / 18 / 29 | 59 / 18 / 28 |
403
+ | vqe_two_local_n6 | 69 / 45 / 25 | 69 / 45 / 25 | 141 / 45 / 37 | 130 / 45 / 44 |
404
+ | qnn_n4 | **11 / 3 / 5** | 20 / 3 / 8 | 39 / 3 / 15 | 13 / 3 / 7 |
405
+ | qnn_n6 | **17 / 5 / 7** | 29 / 5 / 9 | 59 / 5 / 19 | 21 / 5 / 11 |
406
+ | qpeexact_n4 | **18 / 5 / 10** | 20 / 7 / 13 | 25 / 7 / 15 ‡ | 30 / 10 / 21 |
407
+ | qpeexact_n6 | **51 / 16 / 20** | 64 / 27 / 37 | 76 / 27 / 42 ‡ | 96 / 33 / 49 |
408
+ | qpeinexact_n4 | **25 / 7 / 14** | 32 / 12 / 24 | 41 / 12 / 27 ‡ | 43 / 15 / 31 |
409
+ | qpeinexact_n6 | **52 / 17 / 22** | 72 / 30 / 44 | 87 / 30 / 47 ‡ | 103 / 36 / 56 |
410
+ | qwalk_n4 | **250 / 108 / 194** | 262 / 114 / 200 | 288 / 114 / 224 | 316 / 114 / 212 |
411
+ | qwalk_n6 | **1529 / 715 / 1261** | 1838 / 798 / 1382 | 2131 / 798 / 1653 | 2246 / 798 / 1416 |
412
+ | randomcircuit_n4 | **86 / 42 / 66** | 125 / 53 / 96 | 109 / 41 / 82 | 157 / 53 / 102 |
413
+ | randomcircuit_n6 | **180 / 78 / 104** | 229 / 95 / 134 | 272 / 94 / 151 | 269 / 95 / 146 |
414
+ | randomcircuit_n8 | **389 / 170 / 170** | 522 / 208 / 247 | 582 / 207 / 272 ‡ | 657 / 208 / 289 |
415
+ | cdkm_ripple_carry_adder_n4 | **27 / 15 / 25** | 34 / 17 / 26 | 43 / 16 / 30 | 48 / 17 / 32 |
416
+ | cdkm_ripple_carry_adder_n6 | **53 / 29 / 48** | 67 / 33 / 50 | 86 / 31 / 59 | 92 / 33 / 59 |
417
+ | draper_qft_adder_n4 | **15 / 5 / 11** | 20 / 8 / 17 | 25 / 8 / 23 | 23 / 8 / 17 |
418
+ | draper_qft_adder_n6 | **37 / 12 / 19** | 48 / 21 / 35 | 60 / 21 / 40 | 59 / 21 / 38 |
419
+ | grover_n4 | **97 / 44 / 77** | 135 / 52 / 95 | 158 / 52 / 109 | 143 / 52 / 95 |
420
+ | grover_n6 | **897 / 412 / 713** | 1098 / 456 / 818 | 1317 / 456 / 998 | 1287 / 456 / 810 |
421
+ | bv_n5 | 7 / 2 / 4 | 7 / 2 / 4 | 18 / 2 / 8 | 7 / 2 / 4 |
422
+ | bv_n7 | **4 / 3 / 4** | 10 / 3 / 5 | 24 / 3 / 9 | 10 / 3 / 5 |
423
+ | dj_n5 | 13 / 4 / 6 | 13 / 4 / 6 | 27 / 4 / 9 | 13 / 4 / 6 |
424
+ | dj_n7 | 19 / 6 / 8 | 19 / 6 / 8 | 39 / 6 / 11 | 19 / 6 / 8 |
425
+ | ae_n4 | **35 / 11 / 22** | 41 / 12 / 28 | 78 / 12 / 51 | 55 / 18 / 37 |
426
+ | ae_n6 | **66 / 24 / 36** | 92 / 30 / 55 | 145 / 30 / 91 | 125 / 42 / 62 |
427
+
428
+ Tallies (2-qubit count, invalid competitor outputs excluded): compactq wins
429
+ **25 / ties 19 / loses 0** vs Qiskit L3, **25 / 19 / 0** vs Cirq, and **14 / 19 / 1**
430
+ vs pytket — whose default-pipeline output is inequivalent on **10 of 44** circuits
431
+ (‡; the same SWAP-elision pitfall the QASMBench referee shows on pytket 2.18.1;
432
+ Cirq's optimizer was exact on all 44). Reproducibility note: cirq's QASM importer
433
+ and pytket's converter order qubits per register rather than by global wire index,
434
+ so the harness flattens every input onto a single q register first — without that,
435
+ both tools silently optimize the wrong unitary on multi-register circuits.
436
+
437
+ Honest reading: on the unitary QASMBench suite compactq wins or ties Qiskit L3 on
438
+ 2-qubit count on every circuit except basis_trotter_n4 (240 vs 179 — its
439
+ pi/4-quantized iSWAP-ring structure needs deep template analysis; cross-pair
440
+ merging took compactq from 16 to 12 and it is a named roadmap item). At larger
441
+ scales the gap widens: on qft_n29 compactq cuts the 2q count a further 38% below
442
+ Qiskit L3 (370 vs 602) at less than half the depth, on ising_n10 it is the only
443
+ tool that finds non-trivial 2q reductions (49 vs 90), and **adder_n28 flipped from
444
+ the 2026-09-08 loss (422/195 vs 412/195) to a clear win (328/171 vs 412/195)**.
445
+ On latency, Qiskit's Rust core is still the fastest raw optimizer on mid-size
446
+ circuits, but for the same job — an optimized circuit you can actually trust —
447
+ compactq's proof-included time wins the majority of head-to-head circuits, and
448
+ pytket needs external verification on every output (its default mode is
449
+ inequivalent on 10 of 44 MQT and 6 of 30 refereed QASMBench circuits this run).
450
+
451
+ ## CLI
452
+
453
+ Input policy: trailing measurements are dropped (the unitary core is optimized); mid-circuit measurement and reset are rejected with `UnsupportedCircuitError`; the Qiskit bridge rejects them outright (strip them first). The CLI never crashes on width: circuits above the dense proof limit are routed to randomized verification, and every run reports its proof status
454
+
455
+ ```bash
456
+ compact in.qasm -o out.qasm # optimize an OpenQASM 2.0 file
457
+ compact in.qasm --stats # print gate-count/depth deltas
458
+ compact in.qasm --approx 0.99 # bounded-fidelity approximate mode
459
+ python -m compactq.bench # full benchmark vs Qiskit (if installed)
460
+ python -m compactq.bench --quick # 3-circuit CI guard
461
+ compact-bench --out results.md # installed console script
462
+ ```
463
+
464
+ ## API
465
+
466
+ ```python
467
+ import compactq
468
+ compactq.optimize(circuit, verify=True) # Circuit -> Circuit (smaller, verified)
469
+ compactq.optimize_deep(circuit) # KAK cascade, best for dense circuits
470
+ compactq.optimize_search(circuit) # multi-pipeline search, keeps the best
471
+ compactq.approximate(circuit, min_fidelity=0.99) # trade bounded fidelity for fewer 2q gates
472
+ from compactq.target import Target, optimize_for
473
+ t = Target(cx_fidelity={(0, 1): 0.999, (1, 0): 0.98})
474
+ best, est_fid = optimize_for(circuit, t) # least-noisy circuit for YOUR machine
475
+ from compactq.target import approximate_for_target
476
+ best, est_fid = approximate_for_target(circuit, t) # greedy fidelity-budget allocation
477
+ compactq.to_qasm(circuit) / compactq.from_qasm(t) # OpenQASM 2.0 round-trip
478
+ compactq.from_qasm3(t) # OpenQASM 3 import (common subset)
479
+ compactq.to_qasm3(circuit) # OpenQASM 3.0 export
480
+ compactq.benchmarks.qft / ghz / brickwork / random_circuit / clifford_ladder
481
+ compactq.param / compactq.structure_optimize / compactq.bind # symbolic angles: optimize the structure once, bind later
482
+ compactq.optimize_large(circ) # verified optimization to ~30q (randomized K-state proof; numpy)
483
+ ```
484
+
485
+ `from_qasm` understands the full extended-qelib1 set (u1/u2/u3/u, sx, sxdg, cy, cz,
486
+ swap, cswap, ccx, crz, cu1/cp, rzz, rxx, id), multiple registers with global wire
487
+ numbering, register-wide operands (`h q;`) and user `gate` definitions.
488
+ `from_qiskit` accepts any `QuantumCircuit`: gates inside compactq's IR pass through
489
+ untouched, everything else (`mcphase`, `ccx`, `ecr`, `iswap`, `cu`, `rxx`, ...)
490
+ is decomposed at the boundary into the supported basis via Qiskit's own
491
+ equivalence library — loss-free, and the result gets optimized instead of
492
+ crashing.
493
+
494
+ Hardware-aware passes (`compactq.hardware`):
495
+
496
+ ```python
497
+ from compactq.hardware import route, route_aware, flip_cx, translate_1q_to_rz_sx_x
498
+ routed, final_map = route(circuit, coupling=[{0,1},{1,2}])
499
+ routed, final_map = route_aware(circuit, coupling, target=t, restore=True)
500
+ ```
501
+
502
+ `route` inserts SWAPs along shortest paths and returns the final
503
+ logical-on-physical mapping (apply it to your measurements); `route_aware`
504
+ adds SABRE-style re-routing with error-weighted look-ahead and optional
505
+ permutation restore. Optional bridges:
506
+ `compactq.qiskit_bridge` (`compactq_pass`, `to_qiskit`, `from_qiskit`) and
507
+ `compactq.cirq_bridge` (`to_cirq`).
508
+
509
+ Native hardware bases: `Target(native_2q="ecr" | "cz" | "iswap")` with `optimize_for`, or `compact --native ecr` on the CLI (verified gate-count parity with Qiskit's own basis decomposer).
510
+
511
+ Supported gates: `h x y z s sdg t tdg rx ry rz p sx sxdg u/u3 cx cz swap cp`,
512
+ plus `mcx`/`mcp` (expanded on use). Multi-controlled and exotic gates arriving
513
+ via `from_qiskit` are boundary-decomposed automatically.
514
+
515
+ ## Project history
516
+
517
+ - **v0.1.0 — initial public release (2026-09-17).** The verified
518
+ optimizer (peephole / commutation / CP / pure-Python KAK /
519
+ Clifford-tableau / phase-polynomial passes, multi-pipeline search,
520
+ exact + approximate modes, hardware targets, routing, QASM2/3 IO,
521
+ Qiskit bridge + plugin, optional Rust kernels) plus the open
522
+ error-suppression stack (twirling, benefit-gated DD, MLE mitigation,
523
+ ZNE, CDR, simulators, device metrics, execution adapters). See
524
+ [CHANGELOG.md](CHANGELOG.md) for the full inventory.
525
+
526
+ The public version series starts at 0.1.0. An earlier private
527
+ prototyping sprint (local iterations, 2026-09-10 → 2026-09-16)
528
+ produced the engine; those internal numbers are retired and the git
529
+ history keeps the full trail.
530
+
531
+ ## Roadmap
532
+
533
+ - `basis_trotter_n4` final disposition: qiskit's 179 and pytket's 159
534
+ are both *permutation-elided* (unverified outputs; this is exactly
535
+ the circuit where their refereed fidelity was 0.25/0.5). Our 240 is
536
+ exact; matching them requires layer-boundary content-permutation
537
+ search with swap-network payoff at the output (roadmap).
538
+ `basis_test_n4` (the pi/4-quantized ring) has a Clifford+T
539
+ normal-form pass in `compactq/cliffordt.py`; the REAL trotter file
540
+ contains arbitrary-angle PhasedISWAPs and needs a different attack.
541
+ - Rust parity-network BFS kernel: packed
542
+ u64 wire-mask states; exactness fuzzed against the phase-polynomial
543
+ reference (0 failures); parity_pass 302ms -> 25ms on parity-heavy
544
+ shapes; finds windows the Python budget quirk misses
545
+ - port the pass-engine hot path (peephole/KAK driving loops) to Rust to
546
+ close the remaining raw-latency gap vs Qiskit on large circuits
547
+ - MQT Bench in CI (currently a local script: `scripts/mqtbench_run.py`)
548
+
549
+ ## Development
550
+
551
+ ```bash
552
+ git clone https://github.com/Q-PROOF/Compact && cd Compact
553
+ python tests/run_tests.py # zero-dependency test suite
554
+ python scripts/gauntlet.py # 1,018-check end-to-end gauntlet (needs qiskit)
555
+ pip install -e .[bench] # optional: qiskit for the comparison column
556
+ python scripts/realbench.py --size small # QASMBench vs Qiskit/pytket
557
+ python scripts/realbench.py --size large --max-qubits 32
558
+ pip install mqt-bench cirq ply # extras for the fourth suite, then:
559
+ python scripts/mqtbench_run.py # MQT Bench: compactq vs Qiskit/pytket/Cirq
560
+ ```
561
+
562
+ Building the optional Rust wheel:
563
+
564
+ ```bash
565
+ cd native && pip install maturin && maturin build --release -o dist
566
+ pip install dist/compactq_native-*.whl
567
+ ```
568
+
569
+ MIT licensed. Contributions welcome — every PR must keep the property tests green.