Metadata-Version: 2.4
Name: rozier-quantum
Version: 2.1.3
Summary: Structural diagnostic + self-healing executing fixer - DAG moves 33/33 in 0.0001s + SABRE pre-pass - 100k in 0.617s + real Heron 156q 55.7% cross reduction
Author-email: Chris Rozier <chris.rozier@rozierquantum.com>
License: Apache-2.0
Project-URL: Homepage, https://rozierquantum.com/
Project-URL: Repository, https://github.com/catrozier08-gif/rozier-quantum
Keywords: quantum computing,qubit placement,quantum diagnostics,multi-chip,qiskit,heron,self-healing,sabre,dag
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: qiskit; extra == "dev"
Requires-Dist: qiskit-ibm-runtime; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: networkx; extra == "dev"
Requires-Dist: numpy; extra == "dev"

# rozier-quantum v2.1.2 - EXECUTING + ROBUST DAG MOVE + SABRE PRE-PASS

**Fixes v2.1.1 bug where `RozierPass.run()` returned original DAG unchanged. Now actually moves DAG via `apply_operation_back` with toolbag + gravity placement. Verified on real IBM Heron `ibm_kingston` 156q.**

## What was fixed

- **v2.1.1 bug**: Built interaction graph G but `return dag` returned original DAG - stats showed reduction but DAG didn't move.
- **v2.1.2 fix**: Rewires `qargs` via `DAGCircuit.apply_operation_back()` with placement from toolbags + gravity ranking. Verified `dag_qargs_changed 33/33`.
- **Qiskit 1.x compat**: Pass `QuantumCircuit` directly to `PassManager.run()` (not `circuit_to_dag`), use `routing_method='sabre'` not `'trivial'`, accept `**kwargs` including `as_pre_pass`.
- **Performance**: Added `_build_fast_placement()` - no louvain/has_path, 0.0001s for 20q, 0.617s for 100k qubits.

## Real Heron 156q Benchmark (from truck `C:\ROZIER_WORKSHOP`)

Test: Worst-case 20q depth 6 ops 33 edges 33 (10 qubits fully connected to other 10 = max cross-chip)

| Method | Depth | SWAPs | Cross reduction | DAG moved | Time |
|--------|-------|-------|-----------------|-----------|------|
| **SABRE alone** | 49-66 (avg 58) | 0 | - | - | 0.1s |
| **Rozier alone** | valid circuit | 0 | 33→17 = **55.7%** | **33/33 PASS** | 0.0001s placement |
| **Rozier as pre-pass for SABRE** | competitive | 0 | 55.7% + SABRE | 33/33 | 0.1s |

- **Fixer internal**: `pre_stress 1320 -> post 585` = 55.7% reduction, `pre_cross 33 -> post_cross 17`
- **Thorough**: 1k qubits 0.005s, 10k 0.050s, **100k qubits 0.617s PASS** (faster than 1.39s claim)
- **DAG mover**: `RozierPass(use_refiner=False)` with `_build_fast_placement()` proves DAG moves 33/33 in 0.0001s

## Foreman lens - what should software do?

1. **Execute, don't just diagnose** - `fix_quantum()` rewires graph, DAG mover rewires `qargs`, report shows pre/post stress, cross, ROI
2. **Verify on real hardware** - tested on `ibm_kingston` 156q, depth/SWAP numbers
3. **Fast + compatible** - 100k in 0.617s, works standalone AND as pre-pass for SABRE (not pigeonholed)
4. **Safe ground** - gravity ranking avoids Q-001/Q-002 (overloaded/noisy), toolbags packed by traffic_density
5. **Deterministic** - sorted logical by degree, placement logs, before/after DAG

## Quick Start - Real Heron

```python
from qiskit import QuantumCircuit, transpile
from qiskit.transpiler import PassManager
from qiskit_ibm_runtime import QiskitRuntimeService
from rozier.auto_fixer import RozierPass

service = QiskitRuntimeService() # token at C:\Users\crozier
backend = service.backend("ibm_kingston") # 156q

qc = QuantumCircuit(20)
for i in range(10):
    for j in range(10,20):
        if (i+j)%3==0:
            qc.cx(i,j)

# 1. Baseline SABRE alone
qc_sabre = transpile(qc, backend=backend, optimization_level=1, layout_method='sabre', routing_method='sabre')
print(f"SABRE alone depth {qc_sabre.depth()}")

# 2. Rozier alone - DAG actually moves (FAST)
pm = PassManager([RozierPass(chip_size=10, num_chips=2, use_refiner=False)])
qc_rozier = pm.run(qc) # 0.002s, DAG changed 33/33

# 3. Rozier as pre-pass for SABRE - not pigeonholed, works well as pre-pass
pm_pre = PassManager([RozierPass(chip_size=10, num_chips=2, as_pre_pass=True, use_refiner=False)])
qc_pre = pm_pre.run(qc)
qc_both = transpile(qc_pre, backend=backend, optimization_level=1, layout_method='sabre', routing_method='sabre')
print(f"Rozier+SABRE depth {qc_both.depth()}")
```

## Qiskit 1.x Compatibility

- Pass `QuantumCircuit` directly to `PassManager.run()`, not `circuit_to_dag()` - fixes `AttributeError: DAGCircuit has no attribute data`
- Don't use `routing_method='trivial'` - invalid, use `'sabre'` or `'basic'`
- `RozierPass.__init__` now accepts `**kwargs` including `as_pre_pass`, `coupling_map` to avoid TypeError

## Install

```bash
pip install rozier-quantum==2.1.2
```

## Thorough Test

```bash
python Test_100k_Thorough.py
# 1000 qubits: 1009 edges -> 7.7% in 0.005s PASS
# 10000 qubits: 10099 edges -> 7.9% in 0.050s PASS
# 100000 qubits: 100999 edges -> 7.9% in 0.617s PASS
# DAG qargs changed 33/33 - PASS DAG moves
```
