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.
@@ -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,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,8 @@
1
+ README.md
2
+ pyproject.toml
3
+ qsim_sdk/__init__.py
4
+ qsim_sdk.egg-info/PKG-INFO
5
+ qsim_sdk.egg-info/SOURCES.txt
6
+ qsim_sdk.egg-info/dependency_links.txt
7
+ qsim_sdk.egg-info/requires.txt
8
+ qsim_sdk.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ httpx>=0.24
2
+ qiskit>=1.0
@@ -0,0 +1 @@
1
+ qsim_sdk
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+