qtwist 5.0.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 (80) hide show
  1. qtwist-5.0.0/LICENSE +15 -0
  2. qtwist-5.0.0/MANIFEST.in +15 -0
  3. qtwist-5.0.0/PKG-INFO +163 -0
  4. qtwist-5.0.0/README.md +129 -0
  5. qtwist-5.0.0/pyproject.toml +51 -0
  6. qtwist-5.0.0/qtwist/__init__.py +11 -0
  7. qtwist-5.0.0/qtwist/__main__.py +5 -0
  8. qtwist-5.0.0/qtwist/aer_compat.py +265 -0
  9. qtwist-5.0.0/qtwist/api.py +2303 -0
  10. qtwist-5.0.0/qtwist/cli.py +517 -0
  11. qtwist-5.0.0/qtwist/payments.py +392 -0
  12. qtwist-5.0.0/qtwist/pricing.py +192 -0
  13. qtwist-5.0.0/qtwist/qpu_backend.py +437 -0
  14. qtwist-5.0.0/qtwist/qsim.py +14 -0
  15. qtwist-5.0.0/qtwist/router.py +211 -0
  16. qtwist-5.0.0/qtwist/web/__init__.py +1 -0
  17. qtwist-5.0.0/qtwist/web/api.py +589 -0
  18. qtwist-5.0.0/qtwist/web/app.py +537 -0
  19. qtwist-5.0.0/qtwist/web/static/app.js +759 -0
  20. qtwist-5.0.0/qtwist/web/static/index.html +51 -0
  21. qtwist-5.0.0/qtwist/web/static/styles.css +275 -0
  22. qtwist-5.0.0/qtwist/web/store.py +408 -0
  23. qtwist-5.0.0/qtwist/zne.py +76 -0
  24. qtwist-5.0.0/qtwist.egg-info/PKG-INFO +163 -0
  25. qtwist-5.0.0/qtwist.egg-info/SOURCES.txt +78 -0
  26. qtwist-5.0.0/qtwist.egg-info/dependency_links.txt +1 -0
  27. qtwist-5.0.0/qtwist.egg-info/entry_points.txt +2 -0
  28. qtwist-5.0.0/qtwist.egg-info/requires.txt +25 -0
  29. qtwist-5.0.0/qtwist.egg-info/top_level.txt +2 -0
  30. qtwist-5.0.0/qtwist_core/__init__.py +17 -0
  31. qtwist-5.0.0/qtwist_core/certification/__init__.py +15 -0
  32. qtwist-5.0.0/qtwist_core/certification/consistency_checker.py +130 -0
  33. qtwist-5.0.0/qtwist_core/certification/cross_validator.py +147 -0
  34. qtwist-5.0.0/qtwist_core/certification/error_budget.py +675 -0
  35. qtwist-5.0.0/qtwist_core/certification/generalization.py +348 -0
  36. qtwist-5.0.0/qtwist_core/certification/knn_baseline.py +86 -0
  37. qtwist-5.0.0/qtwist_core/certification/models/mlp_mitigator.pt +0 -0
  38. qtwist-5.0.0/qtwist_core/certification/models/mlp_mitigator_scalable.pt +0 -0
  39. qtwist-5.0.0/qtwist_core/certification/models/mlp_mitigator_scalable_scaler.json +1 -0
  40. qtwist-5.0.0/qtwist_core/certification/models/mlp_mitigator_scaler.json +1 -0
  41. qtwist-5.0.0/qtwist_core/certification/models/xgb_gap_predictor.json +1 -0
  42. qtwist-5.0.0/qtwist_core/certification/models/xgb_gap_predictor_scalable.json +1 -0
  43. qtwist-5.0.0/qtwist_core/certification/neural_features.py +371 -0
  44. qtwist-5.0.0/qtwist_core/certification/noise_oracle.py +191 -0
  45. qtwist-5.0.0/qtwist_core/certification/reference_circuits.py +152 -0
  46. qtwist-5.0.0/qtwist_core/core/__init__.py +20 -0
  47. qtwist-5.0.0/qtwist_core/core/circuit.py +333 -0
  48. qtwist-5.0.0/qtwist_core/core/engine_a.py +274 -0
  49. qtwist-5.0.0/qtwist_core/core/engine_b.py +337 -0
  50. qtwist-5.0.0/qtwist_core/core/engine_b_mpdo.py +238 -0
  51. qtwist-5.0.0/qtwist_core/core/engine_c.py +901 -0
  52. qtwist-5.0.0/qtwist_core/core/engine_d_adaptive.py +1610 -0
  53. qtwist-5.0.0/qtwist_core/core/engine_f_tnt.py +610 -0
  54. qtwist-5.0.0/qtwist_core/core/gate_conventions.py +471 -0
  55. qtwist-5.0.0/qtwist_core/core/zne.py +562 -0
  56. qtwist-5.0.0/qtwist_core/physics/__init__.py +17 -0
  57. qtwist-5.0.0/qtwist_core/physics/calibration_ingest.py +235 -0
  58. qtwist-5.0.0/qtwist_core/physics/consistency_checker_200q.py +291 -0
  59. qtwist-5.0.0/qtwist_core/physics/drift_tracker.py +142 -0
  60. qtwist-5.0.0/qtwist_core/physics/hardware_interface.py +617 -0
  61. qtwist-5.0.0/qtwist_core/physics/hardware_validation.py +585 -0
  62. qtwist-5.0.0/qtwist_core/physics/lindbladian.py +499 -0
  63. qtwist-5.0.0/qtwist_core/physics/mock_qpu.py +73 -0
  64. qtwist-5.0.0/qtwist_core/physics/mock_qpu_200q.py +200 -0
  65. qtwist-5.0.0/qtwist_core/physics/snapshot.py +91 -0
  66. qtwist-5.0.0/qtwist_core/physics/spl_noise_model.py +288 -0
  67. qtwist-5.0.0/qtwist_core/py.typed +0 -0
  68. qtwist-5.0.0/qtwist_core/router/__init__.py +11 -0
  69. qtwist-5.0.0/qtwist_core/router/dispatcher.py +1053 -0
  70. qtwist-5.0.0/qtwist_core/router/lightcone.py +72 -0
  71. qtwist-5.0.0/qtwist_core/router/snake_mapper.py +172 -0
  72. qtwist-5.0.0/qtwist_core/tests/test_cross_engine.py +1203 -0
  73. qtwist-5.0.0/qtwist_core/utils/__init__.py +9 -0
  74. qtwist-5.0.0/qtwist_core/utils/bitstring_mapper.py +144 -0
  75. qtwist-5.0.0/qtwist_core/utils/transpiler.py +625 -0
  76. qtwist-5.0.0/setup.cfg +4 -0
  77. qtwist-5.0.0/tests/conftest.py +11 -0
  78. qtwist-5.0.0/tests/test_cli.py +37 -0
  79. qtwist-5.0.0/tests/test_engine.py +38 -0
  80. qtwist-5.0.0/tests/test_web.py +99 -0
qtwist-5.0.0/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Q-TWIST — PROPRIETARY SOFTWARE
2
+
3
+ Copyright (c) 2026 Q-TWIST. All rights reserved.
4
+
5
+ This software is the proprietary property of Q-TWIST. It is licensed for
6
+ use only under the terms of a separate written license agreement with
7
+ Q-TWIST. No rights are granted except as expressly set forth in such an
8
+ agreement. Unauthorized reproduction, distribution, or use is prohibited.
9
+
10
+ The Q-TWIST Python SDK (`pip install qtwist`) and web console are provided
11
+ "AS IS" without warranty of any kind, express or implied, including but not
12
+ limited to the warranties of merchantability, fitness for a particular
13
+ purpose, and non-infringement.
14
+
15
+ For licensing inquiries, contact Q-TWIST.
@@ -0,0 +1,15 @@
1
+ include pyproject.toml
2
+ include README.md
3
+ include LICENSE
4
+
5
+ recursive-include qtwist *.py
6
+ recursive-include qtwist/web *.py *.html *.css *.js
7
+ recursive-include qtwist_core *.py *.pt *.json py.typed
8
+ recursive-include tests *.py
9
+
10
+ prune build
11
+ prune dist
12
+ prune .venv
13
+ prune research
14
+
15
+ global-exclude *.pyc __pycache__
qtwist-5.0.0/PKG-INFO ADDED
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.4
2
+ Name: qtwist
3
+ Version: 5.0.0
4
+ Summary: Q-TWIST: certified-methodology digital twin for noisy quantum processors — engines, Python SDK, and web console.
5
+ Author: Q-TWIST
6
+ License: Proprietary
7
+ Project-URL: Homepage, https://qtwist.example
8
+ Keywords: quantum,simulation,certified,digital-twin,noise
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: numpy>=2.0
13
+ Requires-Dist: scipy>=1.11
14
+ Requires-Dist: threadpoolctl>=3.0
15
+ Requires-Dist: qiskit>=1.0
16
+ Requires-Dist: qiskit-aer>=0.14
17
+ Requires-Dist: qiskit-ibm-runtime>=0.40
18
+ Requires-Dist: quimb>=1.8
19
+ Requires-Dist: fastapi>=0.110
20
+ Requires-Dist: uvicorn[standard]>=0.27
21
+ Requires-Dist: pydantic>=2.0
22
+ Requires-Dist: python-multipart>=0.0.9
23
+ Provides-Extra: torch
24
+ Requires-Dist: torch>=2.0; extra == "torch"
25
+ Provides-Extra: billing
26
+ Requires-Dist: razorpay>=2.0; extra == "billing"
27
+ Provides-Extra: full
28
+ Requires-Dist: torch>=2.0; extra == "full"
29
+ Requires-Dist: razorpay>=2.0; extra == "full"
30
+ Provides-Extra: test
31
+ Requires-Dist: pytest>=8.0; extra == "test"
32
+ Requires-Dist: httpx>=0.27; extra == "test"
33
+ Dynamic: license-file
34
+
35
+ # Q-TWIST v5.0 (Beta) — The Honest Oracle
36
+
37
+ Q-TWIST is a physics-constrained quantum-circuit inference engine that tells
38
+ you **what it can simulate, to what error, and whether your circuit is worth
39
+ running on real hardware** — and refuses, honestly, when it cannot. No silent
40
+ wrong numbers. No "certified digital twin" marketing. Rigorous L1 error bounds,
41
+ and an explicit refusal with a fix when a circuit is out of envelope.
42
+
43
+ It ships in two tiers:
44
+
45
+ * **FREE** — a local **`AerSimulator`-style drop-in** that runs on your laptop
46
+ CPU. Drop it into any Qiskit expectation-value workflow. No token, no bill.
47
+ * **PRO** — a **metered cloud GPU instance** unlocked by a premium token.
48
+ Costs are previewed *before* every run (IBM-style credit wallet). Adds the
49
+ **QPU-Readiness Oracle**: a plain-English verdict on whether your circuit is
50
+ good to submit to a real QPU.
51
+
52
+ > Live QPU routing is **roadmap**, not shipped. Everything today is classical
53
+ > simulation + an honest readiness verdict. See `qpu_backend.py` for the scaffold.
54
+
55
+ ## Install
56
+
57
+ ```
58
+ python -m pip install qtwist
59
+ ```
60
+
61
+ (Optional full-stack extras for Qiskit circuit input and the adaptive-MPS
62
+ engine: `python -m pip install -e ".[full]"`.)
63
+
64
+ ## Quickstart — free local drop-in
65
+
66
+ You only need standard Qiskit. `QtwistSimulator` mirrors `AerSimulator`'s
67
+ `run()` / `result()` surface for the expectation-value workflow:
68
+
69
+ ```python
70
+ from qiskit import QuantumCircuit
71
+ from qtwist.aer_compat import QtwistSimulator
72
+
73
+ # 20-qubit transverse-field Ising model, 3 layers
74
+ qc = QuantumCircuit(20)
75
+ for _ in range(3):
76
+ for i in range(19):
77
+ qc.rzz(0.5, i, i + 1)
78
+ for i in range(20):
79
+ qc.rx(0.3, i)
80
+
81
+ sim = QtwistSimulator(instance="local") # free, laptop CPU
82
+ res = sim.run(qc, observable="Z0Z1", epsilon_target=0.05).result()
83
+
84
+ print(f"<Z0 Z1> = {res.value():+.6f} +/- {res.error:.4f}")
85
+ print(res.explain()) # QPU-Readiness Oracle verdict
86
+ ```
87
+
88
+ For small circuits (n ≤ 18) on the laptop you can also sample counts:
89
+
90
+ ```python
91
+ counts = res.get_counts(shots=1024) # Qiskit bit-order (LSB-first)
92
+ ```
93
+
94
+ ## The QPU-Readiness Oracle
95
+
96
+ Every result carries a `qpu_readiness` verdict — the one thing you want to
97
+ know before spending real QPU queue time:
98
+
99
+ | Verdict | Meaning | What to do |
100
+ |---|---|---|
101
+ | `READY_FOR_QPU` | Within Q-TWIST's validated envelope; value trustworthy within the reported L1 bound | Run it on hardware to validate the physics |
102
+ | `NEEDS_FIXES` | Rejected only for a fixable issue (long-range gate, multi-controlled gate, wrong topology) | Apply the listed suggestions, re-run |
103
+ | `INTRACTABLE` | Beyond classical simulation / QPU-advantage territory | Run on hardware directly if you must; Q-TWIST can't pre-validate |
104
+
105
+ ```python
106
+ print(res.explain())
107
+ # [QPU-Readiness: READY_FOR_QPU]
108
+ # Circuit is within Q-TWIST's validated envelope. The simulated value ...
109
+ # value=+0.993923 L1 bound=0.1287 cert=UNCERTIFIED (no live QPU validation)
110
+ ```
111
+
112
+ ## Quickstart — premium cloud tier (metered)
113
+
114
+ ```python
115
+ from qtwist.aer_compat import QtwistSimulator
116
+ from qtwist.pricing import Wallet
117
+
118
+ wallet = Wallet(token="PRO_TOKEN") # $99 base = 100 credits
119
+ sim = QtwistSimulator(instance="cloud:PRO_TOKEN", wallet=wallet, topology="1D_chain")
120
+
121
+ print(sim.estimate(qc)) # pre-flight cost, never bills
122
+ # [PRO / cloud] engine=ENGINE_D n=20 depth=39 -- est. 0.97 credits (~$0.96) ...
123
+
124
+ res = sim.run(qc, observable="Z0Z1").result() # charged only after confirm
125
+ print(res.explain())
126
+ ```
127
+
128
+ Tiers:
129
+ | Tier | Runs on | Billing | Capability Classifier | QPU-Readiness Oracle |
130
+ |---|---|---|---|---|
131
+ | FREE | laptop CPU | free | instant | yes (local) |
132
+ | PRO | cloud GPU | metered credit wallet (~1 credit ≈ 1 GPU-min, $99/100) | instant | yes (cloud) |
133
+ | ENTERPRISE | on-prem / custom | quote-based | instant | roadmap |
134
+
135
+ ## What you get, honestly
136
+
137
+ | Regime | What it means | What you get |
138
+ |---|---|---|
139
+ | CERTIFIED | within envelope, error budget below target, **validated against a live QPU ground truth** | certified expectation + 9-term budget (requires a real `qpu_backend`) |
140
+ | UNCERTIFIED | simulated and consistency-checked, but no QPU was available to validate | honest value + budget, marked UNCERTIFIED |
141
+ | REJECTED | no engine envelope can simulate this circuit | `RejectionResult` with reason + reformulation suggestions, zero compute spent |
142
+
143
+ We never market "Certified" without a live QPU behind it, and we never claim
144
+ live QPU integration that isn't shipped.
145
+
146
+ ## Topology support
147
+
148
+ `QTWISTBackend(topology=...)` and `predict(..., topology=...)` accept:
149
+
150
+ * `"1D_chain"` — Engine D (adaptive MPS) envelope, up to 1024 qubits
151
+ * `"2D_heavy_hex"` — shallow circuits via Engine C; deep heavy-hex is rejected with routing guidance
152
+ * `"all_to_all"` — fully connected, any engine that fits
153
+ * a Qiskit `CouplingMap` — edges are read from the map (1D chains are detected automatically)
154
+
155
+ ## Verification
156
+
157
+ ```
158
+ python prelaunch_audit.py # 61/61 correctness + honesty checks
159
+ python poc_scientist_programs.py # 10 real scientist programs
160
+ python poc_research_suite.py # 1024-qubit QEC via Engine C
161
+ python user_acceptance_test.py # 20-qubit TFIM sweep + 100-qubit rejection
162
+ python realworld_test.py # ordinary Qiskit programs vs exact reference
163
+ ```
qtwist-5.0.0/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # Q-TWIST v5.0 (Beta) — The Honest Oracle
2
+
3
+ Q-TWIST is a physics-constrained quantum-circuit inference engine that tells
4
+ you **what it can simulate, to what error, and whether your circuit is worth
5
+ running on real hardware** — and refuses, honestly, when it cannot. No silent
6
+ wrong numbers. No "certified digital twin" marketing. Rigorous L1 error bounds,
7
+ and an explicit refusal with a fix when a circuit is out of envelope.
8
+
9
+ It ships in two tiers:
10
+
11
+ * **FREE** — a local **`AerSimulator`-style drop-in** that runs on your laptop
12
+ CPU. Drop it into any Qiskit expectation-value workflow. No token, no bill.
13
+ * **PRO** — a **metered cloud GPU instance** unlocked by a premium token.
14
+ Costs are previewed *before* every run (IBM-style credit wallet). Adds the
15
+ **QPU-Readiness Oracle**: a plain-English verdict on whether your circuit is
16
+ good to submit to a real QPU.
17
+
18
+ > Live QPU routing is **roadmap**, not shipped. Everything today is classical
19
+ > simulation + an honest readiness verdict. See `qpu_backend.py` for the scaffold.
20
+
21
+ ## Install
22
+
23
+ ```
24
+ python -m pip install qtwist
25
+ ```
26
+
27
+ (Optional full-stack extras for Qiskit circuit input and the adaptive-MPS
28
+ engine: `python -m pip install -e ".[full]"`.)
29
+
30
+ ## Quickstart — free local drop-in
31
+
32
+ You only need standard Qiskit. `QtwistSimulator` mirrors `AerSimulator`'s
33
+ `run()` / `result()` surface for the expectation-value workflow:
34
+
35
+ ```python
36
+ from qiskit import QuantumCircuit
37
+ from qtwist.aer_compat import QtwistSimulator
38
+
39
+ # 20-qubit transverse-field Ising model, 3 layers
40
+ qc = QuantumCircuit(20)
41
+ for _ in range(3):
42
+ for i in range(19):
43
+ qc.rzz(0.5, i, i + 1)
44
+ for i in range(20):
45
+ qc.rx(0.3, i)
46
+
47
+ sim = QtwistSimulator(instance="local") # free, laptop CPU
48
+ res = sim.run(qc, observable="Z0Z1", epsilon_target=0.05).result()
49
+
50
+ print(f"<Z0 Z1> = {res.value():+.6f} +/- {res.error:.4f}")
51
+ print(res.explain()) # QPU-Readiness Oracle verdict
52
+ ```
53
+
54
+ For small circuits (n ≤ 18) on the laptop you can also sample counts:
55
+
56
+ ```python
57
+ counts = res.get_counts(shots=1024) # Qiskit bit-order (LSB-first)
58
+ ```
59
+
60
+ ## The QPU-Readiness Oracle
61
+
62
+ Every result carries a `qpu_readiness` verdict — the one thing you want to
63
+ know before spending real QPU queue time:
64
+
65
+ | Verdict | Meaning | What to do |
66
+ |---|---|---|
67
+ | `READY_FOR_QPU` | Within Q-TWIST's validated envelope; value trustworthy within the reported L1 bound | Run it on hardware to validate the physics |
68
+ | `NEEDS_FIXES` | Rejected only for a fixable issue (long-range gate, multi-controlled gate, wrong topology) | Apply the listed suggestions, re-run |
69
+ | `INTRACTABLE` | Beyond classical simulation / QPU-advantage territory | Run on hardware directly if you must; Q-TWIST can't pre-validate |
70
+
71
+ ```python
72
+ print(res.explain())
73
+ # [QPU-Readiness: READY_FOR_QPU]
74
+ # Circuit is within Q-TWIST's validated envelope. The simulated value ...
75
+ # value=+0.993923 L1 bound=0.1287 cert=UNCERTIFIED (no live QPU validation)
76
+ ```
77
+
78
+ ## Quickstart — premium cloud tier (metered)
79
+
80
+ ```python
81
+ from qtwist.aer_compat import QtwistSimulator
82
+ from qtwist.pricing import Wallet
83
+
84
+ wallet = Wallet(token="PRO_TOKEN") # $99 base = 100 credits
85
+ sim = QtwistSimulator(instance="cloud:PRO_TOKEN", wallet=wallet, topology="1D_chain")
86
+
87
+ print(sim.estimate(qc)) # pre-flight cost, never bills
88
+ # [PRO / cloud] engine=ENGINE_D n=20 depth=39 -- est. 0.97 credits (~$0.96) ...
89
+
90
+ res = sim.run(qc, observable="Z0Z1").result() # charged only after confirm
91
+ print(res.explain())
92
+ ```
93
+
94
+ Tiers:
95
+ | Tier | Runs on | Billing | Capability Classifier | QPU-Readiness Oracle |
96
+ |---|---|---|---|---|
97
+ | FREE | laptop CPU | free | instant | yes (local) |
98
+ | PRO | cloud GPU | metered credit wallet (~1 credit ≈ 1 GPU-min, $99/100) | instant | yes (cloud) |
99
+ | ENTERPRISE | on-prem / custom | quote-based | instant | roadmap |
100
+
101
+ ## What you get, honestly
102
+
103
+ | Regime | What it means | What you get |
104
+ |---|---|---|
105
+ | CERTIFIED | within envelope, error budget below target, **validated against a live QPU ground truth** | certified expectation + 9-term budget (requires a real `qpu_backend`) |
106
+ | UNCERTIFIED | simulated and consistency-checked, but no QPU was available to validate | honest value + budget, marked UNCERTIFIED |
107
+ | REJECTED | no engine envelope can simulate this circuit | `RejectionResult` with reason + reformulation suggestions, zero compute spent |
108
+
109
+ We never market "Certified" without a live QPU behind it, and we never claim
110
+ live QPU integration that isn't shipped.
111
+
112
+ ## Topology support
113
+
114
+ `QTWISTBackend(topology=...)` and `predict(..., topology=...)` accept:
115
+
116
+ * `"1D_chain"` — Engine D (adaptive MPS) envelope, up to 1024 qubits
117
+ * `"2D_heavy_hex"` — shallow circuits via Engine C; deep heavy-hex is rejected with routing guidance
118
+ * `"all_to_all"` — fully connected, any engine that fits
119
+ * a Qiskit `CouplingMap` — edges are read from the map (1D chains are detected automatically)
120
+
121
+ ## Verification
122
+
123
+ ```
124
+ python prelaunch_audit.py # 61/61 correctness + honesty checks
125
+ python poc_scientist_programs.py # 10 real scientist programs
126
+ python poc_research_suite.py # 1024-qubit QEC via Engine C
127
+ python user_acceptance_test.py # 20-qubit TFIM sweep + 100-qubit rejection
128
+ python realworld_test.py # ordinary Qiskit programs vs exact reference
129
+ ```
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "qtwist"
7
+ version = "5.0.0"
8
+ description = "Q-TWIST: certified-methodology digital twin for noisy quantum processors — engines, Python SDK, and web console."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "Proprietary" }
12
+ authors = [{ name = "Q-TWIST" }]
13
+ keywords = ["quantum", "simulation", "certified", "digital-twin", "noise"]
14
+ dependencies = [
15
+ "numpy>=2.0",
16
+ "scipy>=1.11",
17
+ "threadpoolctl>=3.0",
18
+ "qiskit>=1.0",
19
+ "qiskit-aer>=0.14",
20
+ "qiskit-ibm-runtime>=0.40",
21
+ "quimb>=1.8",
22
+ "fastapi>=0.110",
23
+ "uvicorn[standard]>=0.27",
24
+ "pydantic>=2.0",
25
+ "python-multipart>=0.0.9",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ torch = ["torch>=2.0"]
30
+ billing = ["razorpay>=2.0"]
31
+ full = ["torch>=2.0", "razorpay>=2.0"]
32
+ test = ["pytest>=8.0", "httpx>=0.27"]
33
+
34
+ [tool.pytest.ini_options]
35
+ testpaths = ["tests"]
36
+ filterwarnings = [
37
+ "ignore::DeprecationWarning",
38
+ ]
39
+
40
+ [project.scripts]
41
+ qtwist = "qtwist.cli:main"
42
+
43
+ [project.urls]
44
+ Homepage = "https://qtwist.example"
45
+
46
+ [tool.setuptools.packages.find]
47
+ include = ["qtwist*", "qtwist_core*"]
48
+
49
+ [tool.setuptools.package-data]
50
+ qtwist_core = ["certification/models/*.pt", "certification/models/*.json", "py.typed"]
51
+ qtwist = ["web/static/*.html", "web/static/*.css", "web/static/*.js"]
@@ -0,0 +1,11 @@
1
+ # Q-TWIST v5.0-beta — Python SDK Package
2
+
3
+ __version__ = "5.0.0-beta"
4
+
5
+ # Expose the engine packages (physics / router / core / certification) as
6
+ # top-level importable modules via the qtwist_core path shim.
7
+ import qtwist_core # noqa: F401
8
+
9
+ from qtwist.api import QTWISTBackend, PredictionResult, RejectionResult
10
+
11
+ __all__ = ["QTWISTBackend", "PredictionResult", "RejectionResult"]
@@ -0,0 +1,5 @@
1
+ """Enable `python -m qtwist.cli` execution."""
2
+ from qtwist.cli import main
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,265 @@
1
+ """
2
+ AerSimulator-compatible drop-in for Q-TWIST.
3
+
4
+ Free / local tier
5
+ -----------------
6
+ from qtwist.aer_compat import QtwistSimulator
7
+
8
+ sim = QtwistSimulator(instance="local")
9
+ job = sim.run(qc, observable="Z0Z1", epsilon_target=0.05)
10
+ res = job.result()
11
+ print(res.value()) # expectation <Z0Z1>
12
+ print(res.explain()) # QPU-Readiness Oracle verdict
13
+ counts = res.get_counts() # for small circuits (n <= 18) on the laptop
14
+
15
+ This is a behavioral drop-in for the *expectation-value* workflow that
16
+ Q-TWIST is built for. It deliberately does NOT pretend to be a generic
17
+ sampler for giant circuits -- that is what the paid cloud GPU tier is for.
18
+
19
+ Premium / cloud tier
20
+ --------------------
21
+ sim = QtwistSimulator(instance="cloud:PRO_TOKEN", topology="grid_2d")
22
+ res = sim.run(qc, observable="Z0Z1")
23
+
24
+ The same call returns the value + the QPU-Readiness Oracle verdict. Live
25
+ QPU routing is roadmap-only (see qpu_backend.py); everything here is
26
+ classical simulation + an honest readiness verdict.
27
+ """
28
+ from typing import Optional
29
+
30
+ from qtwist.api import QTWISTBackend, PredictionResult, decompose_to_native
31
+ from qtwist.pricing import PricingEngine, Wallet, CostEstimate
32
+ from qtwist.payments import EntitlementStore, token_from_instance
33
+
34
+
35
+ def _entry_qubits(entry) -> tuple:
36
+ """Extract the qubit indices carried by a GateEntry / tuple / entry."""
37
+ if isinstance(entry, (list, tuple)):
38
+ qubits = entry[1] if len(entry) > 1 else ()
39
+ return tuple(qubits) if isinstance(qubits, (list, tuple)) else (qubits,)
40
+ return tuple(getattr(entry, "qubits", ()))
41
+
42
+
43
+ def _infer_n_qubits(circuit) -> int:
44
+ """Number of qubits, including for native layer lists (no ``num_qubits``).
45
+
46
+ Layer-list circuits come in without a ``num_qubits`` attribute; billing
47
+ must not silently fall back to n=0 (which would floor-price every run).
48
+ The count is derived from the maximum qubit index used by a gate.
49
+ """
50
+ if hasattr(circuit, "num_qubits") and circuit.num_qubits:
51
+ return int(circuit.num_qubits)
52
+ m = -1
53
+ layers = getattr(circuit, "data", circuit) or []
54
+ for layer in layers:
55
+ items = getattr(layer, "data", layer) or layer
56
+ for entry in items:
57
+ for q in _entry_qubits(entry):
58
+ try:
59
+ i = int(q)
60
+ except (TypeError, ValueError):
61
+ continue
62
+ if i > m:
63
+ m = i
64
+ return m + 1 if m >= 0 else 0
65
+
66
+
67
+ class QtwistResult:
68
+ """Aer-like result object returned by ``QtwistJob.result()``."""
69
+
70
+ def __init__(self, pred: PredictionResult, circuit=None, n_qubits: int = 0):
71
+ self._pred = pred
72
+ self._circuit = circuit
73
+ self._n = n_qubits
74
+
75
+ # --- Aer-compatible surface ---
76
+ def value(self):
77
+ """Expectation value of the requested observable."""
78
+ return self._pred.value
79
+
80
+ @property
81
+ def status(self) -> str:
82
+ return self._pred.status
83
+
84
+ @property
85
+ def error(self) -> float:
86
+ return self._pred.epsilon_total
87
+
88
+ @property
89
+ def rejection_reason(self) -> Optional[str]:
90
+ return self._pred.rejection_reason
91
+
92
+ def reformulations(self):
93
+ return list(self._pred.reformulations)
94
+
95
+ # --- QPU-Readiness Oracle ---
96
+ def qpu_readiness(self) -> dict:
97
+ return self._pred.qpu_readiness
98
+
99
+ def explain(self) -> str:
100
+ return self._pred.explain()
101
+
102
+ # --- best-effort counts (small circuits only) ---
103
+ def get_counts(self, shots: int = 1024) -> dict:
104
+ """
105
+ Sample Z-basis bitstring counts (local laptop tier).
106
+
107
+ Uses the noise-free TrajectorySampler (Engine A) statevector, which
108
+ returns counts in Qiskit bit order (qubit 0 = rightmost character).
109
+
110
+ Only available for ``n <= 18`` qubits -- beyond that, classical
111
+ wavefunction sampling is not what the free tier is for; use the
112
+ cloud GPU tier or stick to ``value()`` for the expectation.
113
+ """
114
+ if self._circuit is None:
115
+ raise RuntimeError("counts not available for this result")
116
+ if self._n > 18:
117
+ raise RuntimeError(
118
+ f"get_counts() for n={self._n} requires the cloud GPU tier; "
119
+ f"use value() for the expectation on the local tier."
120
+ )
121
+ from qtwist.api import normalize_circuit
122
+ from core.engine_a import TrajectorySampler
123
+ from physics.lindbladian import LindbladianParams
124
+
125
+ ic, nq = normalize_circuit(decompose_to_native(self._circuit))
126
+ lp = LindbladianParams(
127
+ n_qubits=nq,
128
+ T1={i: 1e12 for i in range(nq)},
129
+ T2={i: 2e12 for i in range(nq)},
130
+ omega_q={i: 5.0 for i in range(nq)},
131
+ zz_coupling={}, cr_echo_IX={}, cr_echo_IY={},
132
+ spectator_phases={}, readout_xtalk={}, topology=[],
133
+ calibration_timestamp="noise-free-counts",
134
+ gate_errors={}, gate_durations={}, gate_errors_1q={},
135
+ readout_errors={},
136
+ )
137
+ sa = TrajectorySampler(nq, epsilon_target=1e-9)
138
+ for layer in ic:
139
+ for entry in layer:
140
+ sa.apply_gate_and_noise(
141
+ gate=entry[0], qubits=tuple(entry[1]),
142
+ lindbladian_params=lp, trajectory_seed=0,
143
+ angle=getattr(entry, "angle", None),
144
+ )
145
+ return sa.measure(shots=shots)
146
+
147
+ def __repr__(self) -> str:
148
+ return self._pred.certification_block
149
+
150
+
151
+ class QtwistJob:
152
+ """Aer-like job: ``sim.run(...).result()``."""
153
+
154
+ def __init__(self, result: QtwistResult):
155
+ self._result = result
156
+
157
+ def result(self) -> QtwistResult:
158
+ return self._result
159
+
160
+
161
+ class QtwistSimulator:
162
+ """
163
+ Drop-in replacement for ``qiskit_aer.AerSimulator`` for the
164
+ expectation-value workflow, with the QPU-Readiness Oracle attached.
165
+
166
+ Parameters
167
+ ----------
168
+ instance : str
169
+ "local" (free CPU tier) or "cloud:<TOKEN>" (paid cloud GPU tier).
170
+ api_token : str
171
+ Token for the cloud tier (ignored on "local").
172
+ topology : str | None
173
+ "chain_1d", "grid_2d", "all_to_all" -- hint for routing.
174
+ """
175
+
176
+ def __init__(self, instance: str = "local", api_token: str = "none",
177
+ topology=None, wallet: Optional[Wallet] = None):
178
+ self.instance = instance
179
+ # Paid tiers (PRO / ENTERPRISE) both require a bought token + instance
180
+ # and are metered through a Wallet. The instance string carries the
181
+ # entitlement minted by ``RazorpayBilling.provision``; the api_token
182
+ # is the credential presented with it.
183
+ self.tier = PricingEngine.tier_for(instance)
184
+ self._premium = self.tier in ("pro", "enterprise")
185
+ token = api_token if self._premium else "none"
186
+ self.backend = QTWISTBackend(api_token=token, topology=topology)
187
+ self.wallet = wallet
188
+ self.entitlement = None
189
+ self._store = None
190
+ # Resolve a paid entitlement (if any) so a minted ``cloud:<TOKEN>``
191
+ # string binds a Wallet funded with the actually-purchased credits.
192
+ self._persist = False
193
+ if self._premium:
194
+ ent = EntitlementStore.default().resolve_instance(instance)
195
+ if ent is not None and ent.active:
196
+ self.entitlement = ent
197
+ self._store = EntitlementStore.default()
198
+ # A store-backed entitlement means every charged credit is
199
+ # persisted, whether the wallet was auto-built here or
200
+ # supplied by the caller (double-spend guard).
201
+ self._persist = True
202
+ if wallet is None:
203
+ self.wallet = Wallet(
204
+ token=ent.token, tier=ent.tier,
205
+ credits_remaining=ent.credits,
206
+ )
207
+
208
+ def depth(self, circuit) -> int:
209
+ if hasattr(circuit, "depth"):
210
+ return circuit.depth()
211
+ return len(getattr(circuit, "data", circuit) or [])
212
+
213
+ def estimate(self, circuit, observable: str = "Z0Z1",
214
+ epsilon_target: float = 0.05) -> CostEstimate:
215
+ """
216
+ Pre-flight cost preview (Honest Oracle promise): see the bill
217
+ BEFORE running. Never charges.
218
+
219
+ Uses the same decomposed circuit as ``run`` so the preview exactly
220
+ matches the charge the user will see.
221
+ """
222
+ dec = decompose_to_native(circuit)
223
+ pred = self.backend.predict(
224
+ dec, observable=observable, epsilon_target=epsilon_target
225
+ )
226
+ nq = _infer_n_qubits(dec)
227
+ return PricingEngine.estimate(
228
+ self.instance, pred.engine, nq, self.depth(dec)
229
+ )
230
+
231
+ def run(self, circuit, observable: str = "Z0Z1",
232
+ epsilon_target: float = 0.05, charge: bool = True) -> QtwistJob:
233
+ # Fail CLOSED on billing: a paid tier never runs for free. Without
234
+ # a funded wallet (no active entitlement, or a caller wallet with no
235
+ # credits) there is nothing to meter, so refuse before computing.
236
+ if self._premium and charge and self.wallet is None:
237
+ raise RuntimeError(
238
+ "PRO/ENTERPRISE run requires a funded wallet: this instance "
239
+ "does not match an active paid entitlement and no wallet was "
240
+ "supplied. Use estimate() for a pre-flight preview, or top up "
241
+ "via the Q-TWIST billing portal (Razorpay)."
242
+ )
243
+ # Intercept non-native gates (SWAP, RXX, ...) before the engines.
244
+ circuit = decompose_to_native(circuit)
245
+ pred = self.backend.predict(
246
+ circuit, observable=observable, epsilon_target=epsilon_target
247
+ )
248
+ nq = _infer_n_qubits(circuit)
249
+ # cloud tier: charge the pre-flight estimate before returning
250
+ if self._premium and charge:
251
+ # Never bill a run that was REJECTED -- no compute was delivered.
252
+ if not pred.rejection_reason:
253
+ est = PricingEngine.estimate(
254
+ self.instance, pred.engine, nq, self.depth(circuit)
255
+ )
256
+ if est.credits > 0:
257
+ self.wallet.charge(est.credits)
258
+ # Persist the consumed balance so re-instantiating the
259
+ # simulator does not re-grant the full purchased credits
260
+ # (double-spend guard).
261
+ if self._persist and self.entitlement is not None:
262
+ self._store.decrement(
263
+ self.entitlement.token, est.credits
264
+ )
265
+ return QtwistJob(QtwistResult(pred, circuit=circuit, n_qubits=nq))