qsim-sdk 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.
- qsim_sdk-0.1.0/PKG-INFO +95 -0
- qsim_sdk-0.1.0/README.md +75 -0
- qsim_sdk-0.1.0/pyproject.toml +29 -0
- qsim_sdk-0.1.0/qsim_sdk/__init__.py +88 -0
- qsim_sdk-0.1.0/qsim_sdk.egg-info/PKG-INFO +95 -0
- qsim_sdk-0.1.0/qsim_sdk.egg-info/SOURCES.txt +8 -0
- qsim_sdk-0.1.0/qsim_sdk.egg-info/dependency_links.txt +1 -0
- qsim_sdk-0.1.0/qsim_sdk.egg-info/requires.txt +2 -0
- qsim_sdk-0.1.0/qsim_sdk.egg-info/top_level.txt +1 -0
- qsim_sdk-0.1.0/setup.cfg +4 -0
qsim_sdk-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qsim-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Run quantum circuits on CPU, GPU, or real hardware with a certified error estimate on every result
|
|
5
|
+
Author-email: ZKSF <info@zksf.org>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://zksf.org
|
|
8
|
+
Project-URL: Documentation, https://zksf.org/docs
|
|
9
|
+
Project-URL: Console, https://app.zksf.org
|
|
10
|
+
Keywords: quantum,quantum computing,simulator,qiskit,tensor network,clifford,QPU
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: httpx>=0.24
|
|
19
|
+
Requires-Dist: qiskit>=1.0
|
|
20
|
+
|
|
21
|
+
# qsim-sdk
|
|
22
|
+
|
|
23
|
+
Python SDK for [ZKSF](https://zksf.org) (Zero Kelvin Simulation Foundry): run quantum
|
|
24
|
+
circuits on CPU, GPU, or real quantum hardware, and get a certified error estimate on
|
|
25
|
+
every approximate result.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install qsim-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Get an API token from the console at [app.zksf.org](https://app.zksf.org) (sign in,
|
|
32
|
+
then "Copy API token").
|
|
33
|
+
|
|
34
|
+
## Three lines to run a circuit
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import qsim_sdk
|
|
38
|
+
from qiskit import QuantumCircuit
|
|
39
|
+
|
|
40
|
+
qc = QuantumCircuit(3)
|
|
41
|
+
qc.h(0)
|
|
42
|
+
qc.cx(0, 1)
|
|
43
|
+
qc.cx(1, 2)
|
|
44
|
+
qc.measure_all()
|
|
45
|
+
|
|
46
|
+
client = qsim_sdk.Client(token="YOUR_TOKEN")
|
|
47
|
+
job = client.run(qc, shots=1000)
|
|
48
|
+
|
|
49
|
+
print(job["result"]["counts"]) # the outcome histogram
|
|
50
|
+
print(job["result"]["error_info"]) # how much to trust it
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Estimate before you spend
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
est = client.estimate(qc, shots=1000)
|
|
57
|
+
# {'engine': 'clifford', 'predicted_seconds': 0.05,
|
|
58
|
+
# 'predicted_cost_usd': 0.000001, 'reason': '...'}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`estimate()` is free and instant: it tells you which engine will run the circuit,
|
|
62
|
+
roughly how long it will take, and what it will cost, before anything is charged.
|
|
63
|
+
|
|
64
|
+
## Choose an engine explicitly
|
|
65
|
+
|
|
66
|
+
By default the router picks the cheapest adequate simulator (`clifford` for Clifford
|
|
67
|
+
circuits, `exact.cpu` for small ones, `mps.quimb.cpu` for structured larger ones).
|
|
68
|
+
GPU and real hardware are opt-in:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
client.run(qc, engine="exact.gpu") # CUDA statevector
|
|
72
|
+
client.run(qc, engine="qpu.rigetti") # real Rigetti hardware (billed at provider cost)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Hardware jobs may sit in the device queue for minutes to hours; `run()` polls until the
|
|
76
|
+
result attaches. Use `submit()` + `job()` for a non-blocking flow:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
job_id = client.submit(qc, shots=1000, engine="qpu.rigetti")
|
|
80
|
+
job = client.job(job_id) # poll whenever you like
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Error handling
|
|
84
|
+
|
|
85
|
+
`run()` raises instead of returning a bad result silently:
|
|
86
|
+
|
|
87
|
+
- `qsim_sdk.JobRejected` — the circuit is intractable or infeasible for the request
|
|
88
|
+
(the message says why, and what would make it work)
|
|
89
|
+
- `qsim_sdk.JobFailed` — an engine or hardware-provider error
|
|
90
|
+
|
|
91
|
+
## Links
|
|
92
|
+
|
|
93
|
+
- Docs: <https://zksf.org/docs>
|
|
94
|
+
- Console: <https://app.zksf.org>
|
|
95
|
+
- Contact: info@zksf.org
|
qsim_sdk-0.1.0/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# qsim-sdk
|
|
2
|
+
|
|
3
|
+
Python SDK for [ZKSF](https://zksf.org) (Zero Kelvin Simulation Foundry): run quantum
|
|
4
|
+
circuits on CPU, GPU, or real quantum hardware, and get a certified error estimate on
|
|
5
|
+
every approximate result.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install qsim-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Get an API token from the console at [app.zksf.org](https://app.zksf.org) (sign in,
|
|
12
|
+
then "Copy API token").
|
|
13
|
+
|
|
14
|
+
## Three lines to run a circuit
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
import qsim_sdk
|
|
18
|
+
from qiskit import QuantumCircuit
|
|
19
|
+
|
|
20
|
+
qc = QuantumCircuit(3)
|
|
21
|
+
qc.h(0)
|
|
22
|
+
qc.cx(0, 1)
|
|
23
|
+
qc.cx(1, 2)
|
|
24
|
+
qc.measure_all()
|
|
25
|
+
|
|
26
|
+
client = qsim_sdk.Client(token="YOUR_TOKEN")
|
|
27
|
+
job = client.run(qc, shots=1000)
|
|
28
|
+
|
|
29
|
+
print(job["result"]["counts"]) # the outcome histogram
|
|
30
|
+
print(job["result"]["error_info"]) # how much to trust it
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Estimate before you spend
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
est = client.estimate(qc, shots=1000)
|
|
37
|
+
# {'engine': 'clifford', 'predicted_seconds': 0.05,
|
|
38
|
+
# 'predicted_cost_usd': 0.000001, 'reason': '...'}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`estimate()` is free and instant: it tells you which engine will run the circuit,
|
|
42
|
+
roughly how long it will take, and what it will cost, before anything is charged.
|
|
43
|
+
|
|
44
|
+
## Choose an engine explicitly
|
|
45
|
+
|
|
46
|
+
By default the router picks the cheapest adequate simulator (`clifford` for Clifford
|
|
47
|
+
circuits, `exact.cpu` for small ones, `mps.quimb.cpu` for structured larger ones).
|
|
48
|
+
GPU and real hardware are opt-in:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
client.run(qc, engine="exact.gpu") # CUDA statevector
|
|
52
|
+
client.run(qc, engine="qpu.rigetti") # real Rigetti hardware (billed at provider cost)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Hardware jobs may sit in the device queue for minutes to hours; `run()` polls until the
|
|
56
|
+
result attaches. Use `submit()` + `job()` for a non-blocking flow:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
job_id = client.submit(qc, shots=1000, engine="qpu.rigetti")
|
|
60
|
+
job = client.job(job_id) # poll whenever you like
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Error handling
|
|
64
|
+
|
|
65
|
+
`run()` raises instead of returning a bad result silently:
|
|
66
|
+
|
|
67
|
+
- `qsim_sdk.JobRejected` — the circuit is intractable or infeasible for the request
|
|
68
|
+
(the message says why, and what would make it work)
|
|
69
|
+
- `qsim_sdk.JobFailed` — an engine or hardware-provider error
|
|
70
|
+
|
|
71
|
+
## Links
|
|
72
|
+
|
|
73
|
+
- Docs: <https://zksf.org/docs>
|
|
74
|
+
- Console: <https://app.zksf.org>
|
|
75
|
+
- Contact: info@zksf.org
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "qsim-sdk"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Run quantum circuits on CPU, GPU, or real hardware with a certified error estimate on every result"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name = "ZKSF", email = "info@zksf.org" }]
|
|
9
|
+
keywords = ["quantum", "quantum computing", "simulator", "qiskit", "tensor network", "clifford", "QPU"]
|
|
10
|
+
dependencies = ["httpx>=0.24", "qiskit>=1.0"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 4 - Beta",
|
|
13
|
+
"Intended Audience :: Science/Research",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://zksf.org"
|
|
21
|
+
Documentation = "https://zksf.org/docs"
|
|
22
|
+
Console = "https://app.zksf.org"
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["setuptools>=68"]
|
|
26
|
+
build-backend = "setuptools.build_meta"
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.packages.find]
|
|
29
|
+
include = ["qsim_sdk*"]
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""qsim SDK — three lines to run a circuit:
|
|
2
|
+
|
|
3
|
+
import qsim_sdk
|
|
4
|
+
client = qsim_sdk.Client("http://localhost:8000")
|
|
5
|
+
result = client.run(qiskit_circuit)
|
|
6
|
+
|
|
7
|
+
result["result"]["counts"] # outcomes
|
|
8
|
+
result["result"]["error_info"] # how much to trust them <- the point
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import time
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
import httpx
|
|
16
|
+
from qiskit import QuantumCircuit, qasm2
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class JobRejected(RuntimeError):
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class JobFailed(RuntimeError):
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DEFAULT_BASE_URL = "https://api.zksf.org"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Client:
|
|
31
|
+
def __init__(self, base_url: str = DEFAULT_BASE_URL, token: str | None = None):
|
|
32
|
+
headers = {"Authorization": f"Bearer {token}"} if token else {}
|
|
33
|
+
self._http = httpx.Client(base_url=base_url, headers=headers, timeout=600.0)
|
|
34
|
+
|
|
35
|
+
def estimate(self, circuit: QuantumCircuit, shots: int = 1024) -> dict[str, Any]:
|
|
36
|
+
"""Free pre-run check: engine, predicted runtime and cost, or why not."""
|
|
37
|
+
resp = self._http.post(
|
|
38
|
+
"/estimate", json={"qasm2": qasm2.dumps(circuit), "shots": shots}
|
|
39
|
+
)
|
|
40
|
+
resp.raise_for_status()
|
|
41
|
+
return resp.json()
|
|
42
|
+
|
|
43
|
+
def submit(
|
|
44
|
+
self,
|
|
45
|
+
circuit: QuantumCircuit,
|
|
46
|
+
shots: int = 1024,
|
|
47
|
+
engine: str | None = None,
|
|
48
|
+
**params: Any,
|
|
49
|
+
) -> str:
|
|
50
|
+
resp = self._http.post(
|
|
51
|
+
"/jobs",
|
|
52
|
+
json={
|
|
53
|
+
"qasm2": qasm2.dumps(circuit),
|
|
54
|
+
"shots": shots,
|
|
55
|
+
"engine": engine,
|
|
56
|
+
"params": params,
|
|
57
|
+
},
|
|
58
|
+
)
|
|
59
|
+
resp.raise_for_status()
|
|
60
|
+
return resp.json()["id"]
|
|
61
|
+
|
|
62
|
+
def job(self, job_id: str) -> dict[str, Any]:
|
|
63
|
+
resp = self._http.get(f"/jobs/{job_id}")
|
|
64
|
+
resp.raise_for_status()
|
|
65
|
+
return resp.json()
|
|
66
|
+
|
|
67
|
+
def run(
|
|
68
|
+
self,
|
|
69
|
+
circuit: QuantumCircuit,
|
|
70
|
+
shots: int = 1024,
|
|
71
|
+
engine: str | None = None,
|
|
72
|
+
poll_seconds: float = 0.2,
|
|
73
|
+
timeout: float = 600.0,
|
|
74
|
+
**params: Any,
|
|
75
|
+
) -> dict[str, Any]:
|
|
76
|
+
"""Submit and wait. Raises JobRejected/JobFailed with the honest reason."""
|
|
77
|
+
job_id = self.submit(circuit, shots=shots, engine=engine, **params)
|
|
78
|
+
deadline = time.monotonic() + timeout
|
|
79
|
+
while time.monotonic() < deadline:
|
|
80
|
+
job = self.job(job_id)
|
|
81
|
+
if job["status"] == "done":
|
|
82
|
+
return job
|
|
83
|
+
if job["status"] == "rejected":
|
|
84
|
+
raise JobRejected(job["reason"])
|
|
85
|
+
if job["status"] == "error":
|
|
86
|
+
raise JobFailed(job["error"])
|
|
87
|
+
time.sleep(poll_seconds)
|
|
88
|
+
raise TimeoutError(f"job {job_id} still running after {timeout}s")
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qsim-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Run quantum circuits on CPU, GPU, or real hardware with a certified error estimate on every result
|
|
5
|
+
Author-email: ZKSF <info@zksf.org>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://zksf.org
|
|
8
|
+
Project-URL: Documentation, https://zksf.org/docs
|
|
9
|
+
Project-URL: Console, https://app.zksf.org
|
|
10
|
+
Keywords: quantum,quantum computing,simulator,qiskit,tensor network,clifford,QPU
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: httpx>=0.24
|
|
19
|
+
Requires-Dist: qiskit>=1.0
|
|
20
|
+
|
|
21
|
+
# qsim-sdk
|
|
22
|
+
|
|
23
|
+
Python SDK for [ZKSF](https://zksf.org) (Zero Kelvin Simulation Foundry): run quantum
|
|
24
|
+
circuits on CPU, GPU, or real quantum hardware, and get a certified error estimate on
|
|
25
|
+
every approximate result.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install qsim-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Get an API token from the console at [app.zksf.org](https://app.zksf.org) (sign in,
|
|
32
|
+
then "Copy API token").
|
|
33
|
+
|
|
34
|
+
## Three lines to run a circuit
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import qsim_sdk
|
|
38
|
+
from qiskit import QuantumCircuit
|
|
39
|
+
|
|
40
|
+
qc = QuantumCircuit(3)
|
|
41
|
+
qc.h(0)
|
|
42
|
+
qc.cx(0, 1)
|
|
43
|
+
qc.cx(1, 2)
|
|
44
|
+
qc.measure_all()
|
|
45
|
+
|
|
46
|
+
client = qsim_sdk.Client(token="YOUR_TOKEN")
|
|
47
|
+
job = client.run(qc, shots=1000)
|
|
48
|
+
|
|
49
|
+
print(job["result"]["counts"]) # the outcome histogram
|
|
50
|
+
print(job["result"]["error_info"]) # how much to trust it
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Estimate before you spend
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
est = client.estimate(qc, shots=1000)
|
|
57
|
+
# {'engine': 'clifford', 'predicted_seconds': 0.05,
|
|
58
|
+
# 'predicted_cost_usd': 0.000001, 'reason': '...'}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`estimate()` is free and instant: it tells you which engine will run the circuit,
|
|
62
|
+
roughly how long it will take, and what it will cost, before anything is charged.
|
|
63
|
+
|
|
64
|
+
## Choose an engine explicitly
|
|
65
|
+
|
|
66
|
+
By default the router picks the cheapest adequate simulator (`clifford` for Clifford
|
|
67
|
+
circuits, `exact.cpu` for small ones, `mps.quimb.cpu` for structured larger ones).
|
|
68
|
+
GPU and real hardware are opt-in:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
client.run(qc, engine="exact.gpu") # CUDA statevector
|
|
72
|
+
client.run(qc, engine="qpu.rigetti") # real Rigetti hardware (billed at provider cost)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Hardware jobs may sit in the device queue for minutes to hours; `run()` polls until the
|
|
76
|
+
result attaches. Use `submit()` + `job()` for a non-blocking flow:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
job_id = client.submit(qc, shots=1000, engine="qpu.rigetti")
|
|
80
|
+
job = client.job(job_id) # poll whenever you like
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Error handling
|
|
84
|
+
|
|
85
|
+
`run()` raises instead of returning a bad result silently:
|
|
86
|
+
|
|
87
|
+
- `qsim_sdk.JobRejected` — the circuit is intractable or infeasible for the request
|
|
88
|
+
(the message says why, and what would make it work)
|
|
89
|
+
- `qsim_sdk.JobFailed` — an engine or hardware-provider error
|
|
90
|
+
|
|
91
|
+
## Links
|
|
92
|
+
|
|
93
|
+
- Docs: <https://zksf.org/docs>
|
|
94
|
+
- Console: <https://app.zksf.org>
|
|
95
|
+
- Contact: info@zksf.org
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qsim_sdk
|
qsim_sdk-0.1.0/setup.cfg
ADDED