ojanvu 1.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.
- ojanvu-1.0.0/PKG-INFO +69 -0
- ojanvu-1.0.0/README.md +55 -0
- ojanvu-1.0.0/ojanvu/__init__.py +11 -0
- ojanvu-1.0.0/ojanvu/driver.py +243 -0
- ojanvu-1.0.0/ojanvu/qpu.py +171 -0
- ojanvu-1.0.0/ojanvu/security.py +92 -0
- ojanvu-1.0.0/ojanvu.egg-info/PKG-INFO +69 -0
- ojanvu-1.0.0/ojanvu.egg-info/SOURCES.txt +12 -0
- ojanvu-1.0.0/ojanvu.egg-info/dependency_links.txt +1 -0
- ojanvu-1.0.0/ojanvu.egg-info/requires.txt +1 -0
- ojanvu-1.0.0/ojanvu.egg-info/top_level.txt +1 -0
- ojanvu-1.0.0/pyproject.toml +18 -0
- ojanvu-1.0.0/setup.cfg +4 -0
- ojanvu-1.0.0/setup.py +15 -0
ojanvu-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ojanvu
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for Ojanvu Continuous-Variable Quantum Computing Processors
|
|
5
|
+
Author: Ojanvu Quantum Labs
|
|
6
|
+
Author-email: Ojanvu Quantum Labs <contact@ojanvu.com>
|
|
7
|
+
License: Proprietary
|
|
8
|
+
Project-URL: Homepage, https://ojanvu.com
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: pyserial>=3.5
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
|
|
15
|
+
# Ojanvu Python SDK (`ojanvu`) v1.0.0
|
|
16
|
+
|
|
17
|
+
The official Python client library for executing quantum programs on **Ojanvu Continuous-Variable Quantum Computing (CVQC)** hardware.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install ojanvu
|
|
23
|
+
```
|
|
24
|
+
Or install locally in development mode:
|
|
25
|
+
```bash
|
|
26
|
+
pip install -e python/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from ojanvu import Planck2
|
|
33
|
+
|
|
34
|
+
# Auto-detects port, securely authenticates, and initializes the quantum photonic core
|
|
35
|
+
qpu = Planck2()
|
|
36
|
+
|
|
37
|
+
# Execute OpenQASM circuit
|
|
38
|
+
qasm_circuit = """
|
|
39
|
+
qreg q[2];
|
|
40
|
+
creg c[2];
|
|
41
|
+
h q[0];
|
|
42
|
+
cx q[0], q[1];
|
|
43
|
+
measure q -> c;
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
result = qpu.execute(qasm_circuit, shots=1000)
|
|
47
|
+
print("Measurement Counts:", result.get_counts())
|
|
48
|
+
print("Probabilities:", result.get_probabilities())
|
|
49
|
+
|
|
50
|
+
# Clean session release
|
|
51
|
+
qpu.close()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Context Manager Support
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from ojanvu import Planck2
|
|
58
|
+
|
|
59
|
+
with Planck2() as qpu:
|
|
60
|
+
diag = qpu.get_optical_diagnostics()
|
|
61
|
+
print("Optical Interlock Status:", diag["optical_status"])
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Core Capabilities
|
|
65
|
+
- **OpenQASM Execution:** Discrete-variable logical qubits via 3:1 Sovereign Chromatic QEC.
|
|
66
|
+
- **Continuous-Variable Execution (CV-QASM):** Native photonic qumodes, phase rotations, and displacement operations.
|
|
67
|
+
- **Hardware Solvers:** Built-in hardware VQE, QUBO optimization, and Thermodynamic Integration (TI).
|
|
68
|
+
- **Session Protection:** Automatic keepalive heartbeat prevents session timeout during long benchmarks.
|
|
69
|
+
|
ojanvu-1.0.0/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Ojanvu Python SDK (`ojanvu`) v1.0.0
|
|
2
|
+
|
|
3
|
+
The official Python client library for executing quantum programs on **Ojanvu Continuous-Variable Quantum Computing (CVQC)** hardware.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install ojanvu
|
|
9
|
+
```
|
|
10
|
+
Or install locally in development mode:
|
|
11
|
+
```bash
|
|
12
|
+
pip install -e python/
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from ojanvu import Planck2
|
|
19
|
+
|
|
20
|
+
# Auto-detects port, securely authenticates, and initializes the quantum photonic core
|
|
21
|
+
qpu = Planck2()
|
|
22
|
+
|
|
23
|
+
# Execute OpenQASM circuit
|
|
24
|
+
qasm_circuit = """
|
|
25
|
+
qreg q[2];
|
|
26
|
+
creg c[2];
|
|
27
|
+
h q[0];
|
|
28
|
+
cx q[0], q[1];
|
|
29
|
+
measure q -> c;
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
result = qpu.execute(qasm_circuit, shots=1000)
|
|
33
|
+
print("Measurement Counts:", result.get_counts())
|
|
34
|
+
print("Probabilities:", result.get_probabilities())
|
|
35
|
+
|
|
36
|
+
# Clean session release
|
|
37
|
+
qpu.close()
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Context Manager Support
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from ojanvu import Planck2
|
|
44
|
+
|
|
45
|
+
with Planck2() as qpu:
|
|
46
|
+
diag = qpu.get_optical_diagnostics()
|
|
47
|
+
print("Optical Interlock Status:", diag["optical_status"])
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Core Capabilities
|
|
51
|
+
- **OpenQASM Execution:** Discrete-variable logical qubits via 3:1 Sovereign Chromatic QEC.
|
|
52
|
+
- **Continuous-Variable Execution (CV-QASM):** Native photonic qumodes, phase rotations, and displacement operations.
|
|
53
|
+
- **Hardware Solvers:** Built-in hardware VQE, QUBO optimization, and Thermodynamic Integration (TI).
|
|
54
|
+
- **Session Protection:** Automatic keepalive heartbeat prevents session timeout during long benchmarks.
|
|
55
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ojanvu Quantum Software Development Kit (SDK)
|
|
3
|
+
Copyright (c) 2026 Ojanvu Quantum Labs. All rights reserved.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .qpu import Planck2, JobResult
|
|
7
|
+
from .driver import list_ports, auto_detect_port
|
|
8
|
+
|
|
9
|
+
__version__ = "1.0.0"
|
|
10
|
+
__all__ = ["Planck2", "JobResult", "list_ports", "auto_detect_port"]
|
|
11
|
+
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ojanvu Planck 2 Quantum Core Hardware Communication Driver
|
|
3
|
+
Copyright (c) 2026 Ojanvu Quantum Labs. All rights reserved.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import glob
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import threading
|
|
11
|
+
import time
|
|
12
|
+
import serial
|
|
13
|
+
from .security import authenticate_hardware
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def list_ports():
|
|
17
|
+
"""Lists candidate system hardware ports."""
|
|
18
|
+
ports = []
|
|
19
|
+
if sys.platform.startswith("darwin"):
|
|
20
|
+
ports = glob.glob("/dev/cu.usbmodem*") + glob.glob("/dev/cu.usbserial*")
|
|
21
|
+
elif sys.platform.startswith("linux"):
|
|
22
|
+
ports = glob.glob("/dev/ttyACM*") + glob.glob("/dev/ttyUSB*")
|
|
23
|
+
elif sys.platform.startswith("win"):
|
|
24
|
+
ports = [f"COM{i}" for i in range(1, 32)]
|
|
25
|
+
return sorted(list(set(ports)))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def auto_detect_port():
|
|
29
|
+
"""Dynamically resolves the active Planck 2 QPU port."""
|
|
30
|
+
env_port = os.environ.get("OJANVU_PORT") or os.environ.get("PLANCK2_PORT")
|
|
31
|
+
if env_port and (os.path.exists(env_port) or sys.platform.startswith("win")):
|
|
32
|
+
return env_port
|
|
33
|
+
|
|
34
|
+
candidates = list_ports()
|
|
35
|
+
if candidates:
|
|
36
|
+
return candidates[0]
|
|
37
|
+
return None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class Planck2Driver:
|
|
41
|
+
"""Low-level driver handling hardware connection, security, and session keepalive."""
|
|
42
|
+
|
|
43
|
+
def __init__(self, port=None, baudrate=115200, timeout=15.0):
|
|
44
|
+
self.port = port or auto_detect_port()
|
|
45
|
+
self.baudrate = baudrate
|
|
46
|
+
self.timeout = timeout
|
|
47
|
+
self.ser = None
|
|
48
|
+
self._lock = threading.Lock()
|
|
49
|
+
self._last_activity = time.time()
|
|
50
|
+
self._running = False
|
|
51
|
+
self._keepalive_thread = None
|
|
52
|
+
|
|
53
|
+
def connect(self):
|
|
54
|
+
"""Establishes physical bus link, arms quantum core, and starts session keepalive."""
|
|
55
|
+
if not self.port:
|
|
56
|
+
raise ConnectionError(
|
|
57
|
+
"No Planck 2 hardware port detected. Please verify USB connection or specify port."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
with self._lock:
|
|
61
|
+
try:
|
|
62
|
+
self.ser = serial.Serial(self.port, self.baudrate, timeout=self.timeout)
|
|
63
|
+
time.sleep(1.2) # Allow boot settling
|
|
64
|
+
except Exception as e:
|
|
65
|
+
raise ConnectionError(f"Failed to open hardware communication interface at {self.port}: {e}")
|
|
66
|
+
|
|
67
|
+
# Silent cryptographic authentication
|
|
68
|
+
ok = authenticate_hardware(self.ser, timeout=3.5)
|
|
69
|
+
if not ok:
|
|
70
|
+
raise PermissionError("QPU hardware rejected driver authentication.")
|
|
71
|
+
|
|
72
|
+
# Flush stale startup bytes
|
|
73
|
+
self.ser.reset_input_buffer()
|
|
74
|
+
self._last_activity = time.time()
|
|
75
|
+
|
|
76
|
+
# Start background session maintainer
|
|
77
|
+
self._running = True
|
|
78
|
+
self._keepalive_thread = threading.Thread(target=self._keepalive_loop, daemon=True)
|
|
79
|
+
self._keepalive_thread.start()
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
def _keepalive_loop(self):
|
|
83
|
+
"""Maintains session state and prevents watchdog timeout during long test suites."""
|
|
84
|
+
while self._running:
|
|
85
|
+
time.sleep(4.0)
|
|
86
|
+
if not self._running:
|
|
87
|
+
break
|
|
88
|
+
# If no command was sent in the last 6 seconds, send a lightweight heartbeat
|
|
89
|
+
if time.time() - self._last_activity > 6.0:
|
|
90
|
+
with self._lock:
|
|
91
|
+
if self.ser and self.ser.is_open:
|
|
92
|
+
try:
|
|
93
|
+
self.ser.write(b"KEEPALIVE\n")
|
|
94
|
+
self.ser.flush()
|
|
95
|
+
t0 = time.time()
|
|
96
|
+
while time.time() - t0 < 0.5:
|
|
97
|
+
if self.ser.in_waiting > 0:
|
|
98
|
+
resp = self.ser.readline().decode("utf-8", errors="ignore").strip()
|
|
99
|
+
if "PONG" in resp:
|
|
100
|
+
self._last_activity = time.time()
|
|
101
|
+
break
|
|
102
|
+
time.sleep(0.02)
|
|
103
|
+
except Exception:
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
def send_command(self, cmd_str: str, timeout: float = 5.0) -> list:
|
|
107
|
+
"""Sends a single high-level command to the quantum processor and returns lines."""
|
|
108
|
+
with self._lock:
|
|
109
|
+
if not self.ser or not self.ser.is_open:
|
|
110
|
+
raise ConnectionError("Hardware interface is disconnected.")
|
|
111
|
+
|
|
112
|
+
self.ser.reset_input_buffer()
|
|
113
|
+
if not cmd_str.endswith("\n"):
|
|
114
|
+
cmd_str += "\n"
|
|
115
|
+
self.ser.write(cmd_str.encode("utf-8"))
|
|
116
|
+
self.ser.flush()
|
|
117
|
+
self._last_activity = time.time()
|
|
118
|
+
|
|
119
|
+
lines = []
|
|
120
|
+
t0 = time.time()
|
|
121
|
+
time.sleep(0.04)
|
|
122
|
+
while time.time() - t0 < timeout:
|
|
123
|
+
if self.ser.in_waiting > 0:
|
|
124
|
+
l = self.ser.readline().decode("utf-8", errors="ignore").strip()
|
|
125
|
+
if l:
|
|
126
|
+
lines.append(l)
|
|
127
|
+
self._last_activity = time.time()
|
|
128
|
+
else:
|
|
129
|
+
if lines and time.time() - t0 > 0.2:
|
|
130
|
+
break
|
|
131
|
+
time.sleep(0.02)
|
|
132
|
+
return lines
|
|
133
|
+
|
|
134
|
+
def execute_qasm(self, qasm_code: str, shots: int = 500, timeout: float = 30.0) -> dict:
|
|
135
|
+
"""Transmits QASM circuit program and collects shot measurement distributions."""
|
|
136
|
+
with self._lock:
|
|
137
|
+
if not self.ser or not self.ser.is_open:
|
|
138
|
+
raise ConnectionError("Hardware interface is disconnected.")
|
|
139
|
+
|
|
140
|
+
self.ser.reset_input_buffer()
|
|
141
|
+
self.ser.write(f"shots {shots}\n".encode("utf-8"))
|
|
142
|
+
time.sleep(0.02)
|
|
143
|
+
self.ser.write(b"qasm\n")
|
|
144
|
+
time.sleep(0.02)
|
|
145
|
+
|
|
146
|
+
for line in qasm_code.strip().split("\n"):
|
|
147
|
+
line = line.strip()
|
|
148
|
+
if line and not line.startswith("//"):
|
|
149
|
+
self.ser.write(f"{line}\n".encode("utf-8"))
|
|
150
|
+
time.sleep(0.008)
|
|
151
|
+
|
|
152
|
+
self.ser.write(b"END\n")
|
|
153
|
+
self.ser.flush()
|
|
154
|
+
self._last_activity = time.time()
|
|
155
|
+
|
|
156
|
+
t0 = time.time()
|
|
157
|
+
counts = {}
|
|
158
|
+
total_shots = 0
|
|
159
|
+
raw_lines = []
|
|
160
|
+
|
|
161
|
+
while time.time() - t0 < timeout:
|
|
162
|
+
if self.ser.in_waiting > 0:
|
|
163
|
+
l = self.ser.readline().decode("utf-8", errors="ignore").strip()
|
|
164
|
+
if l:
|
|
165
|
+
raw_lines.append(l)
|
|
166
|
+
self._last_activity = time.time()
|
|
167
|
+
|
|
168
|
+
if "{\"qasm_result\"" in l or "{\"counts\"" in l:
|
|
169
|
+
try:
|
|
170
|
+
d = json.loads(l)
|
|
171
|
+
q_res = d.get("qasm_result", d)
|
|
172
|
+
counts = q_res.get("counts", {})
|
|
173
|
+
total_shots = sum(counts.values())
|
|
174
|
+
if total_shots > 0:
|
|
175
|
+
return {"counts": counts, "shots": total_shots, "raw": raw_lines}
|
|
176
|
+
except Exception:
|
|
177
|
+
pass
|
|
178
|
+
elif l.startswith("|") and ":" in l:
|
|
179
|
+
try:
|
|
180
|
+
state_part, count_part = l.split(":")
|
|
181
|
+
st = state_part.replace("|", "").replace(">", "").strip()
|
|
182
|
+
cnt = int(count_part.split()[0].strip())
|
|
183
|
+
counts[st] = cnt
|
|
184
|
+
except Exception:
|
|
185
|
+
pass
|
|
186
|
+
elif "QASM Program Complete" in l or "Execution complete" in l:
|
|
187
|
+
if counts:
|
|
188
|
+
return {"counts": counts, "shots": sum(counts.values()), "raw": raw_lines}
|
|
189
|
+
else:
|
|
190
|
+
time.sleep(0.02)
|
|
191
|
+
|
|
192
|
+
if counts:
|
|
193
|
+
return {"counts": counts, "shots": sum(counts.values()), "raw": raw_lines}
|
|
194
|
+
raise TimeoutError(f"QPU execution did not return state counts within {timeout}s.")
|
|
195
|
+
|
|
196
|
+
def execute_cv(self, cv_script: str, timeout: float = 15.0) -> dict:
|
|
197
|
+
"""Executes Continuous-Variable CV-QASM operations on optical qumodes."""
|
|
198
|
+
with self._lock:
|
|
199
|
+
if not self.ser or not self.ser.is_open:
|
|
200
|
+
raise ConnectionError("Hardware interface is disconnected.")
|
|
201
|
+
|
|
202
|
+
self.ser.reset_input_buffer()
|
|
203
|
+
self.ser.write(b"cv\n")
|
|
204
|
+
time.sleep(0.02)
|
|
205
|
+
for line in cv_script.strip().split("\n"):
|
|
206
|
+
l = line.strip()
|
|
207
|
+
if l and not l.startswith("#"):
|
|
208
|
+
self.ser.write(f"{l}\n".encode("utf-8"))
|
|
209
|
+
time.sleep(0.008)
|
|
210
|
+
self.ser.write(b"END\n")
|
|
211
|
+
self.ser.flush()
|
|
212
|
+
self._last_activity = time.time()
|
|
213
|
+
|
|
214
|
+
t0 = time.time()
|
|
215
|
+
res = {}
|
|
216
|
+
while time.time() - t0 < timeout:
|
|
217
|
+
if self.ser.in_waiting > 0:
|
|
218
|
+
l = self.ser.readline().decode("utf-8", errors="ignore").strip()
|
|
219
|
+
if "{\"cv_result\"" in l:
|
|
220
|
+
try:
|
|
221
|
+
res = json.loads(l).get("cv_result", {})
|
|
222
|
+
return res
|
|
223
|
+
except Exception:
|
|
224
|
+
pass
|
|
225
|
+
time.sleep(0.02)
|
|
226
|
+
return res
|
|
227
|
+
|
|
228
|
+
def close(self):
|
|
229
|
+
"""Cleanly terminates session, disarms laser core, and secures hardware."""
|
|
230
|
+
self._running = False
|
|
231
|
+
with self._lock:
|
|
232
|
+
if self.ser and self.ser.is_open:
|
|
233
|
+
try:
|
|
234
|
+
self.ser.write(b"o\n") # optical carriers off
|
|
235
|
+
time.sleep(0.02)
|
|
236
|
+
self.ser.write(b"LOCK\n") # hardware locked
|
|
237
|
+
self.ser.flush()
|
|
238
|
+
time.sleep(0.05)
|
|
239
|
+
self.ser.close()
|
|
240
|
+
except Exception:
|
|
241
|
+
pass
|
|
242
|
+
self.ser = None
|
|
243
|
+
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ojanvu Planck 2 Quantum Processing Unit (QPU) High-Level Interface
|
|
3
|
+
Copyright (c) 2026 Ojanvu Quantum Labs. All rights reserved.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import time
|
|
8
|
+
from .driver import Planck2Driver
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class JobResult:
|
|
12
|
+
"""Represents the measurement outcomes and execution telemetry of a quantum job."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, counts: dict, total_shots: int, raw_records: list = None, execution_time: float = 0.0):
|
|
15
|
+
self.counts = counts
|
|
16
|
+
self.shots = total_shots
|
|
17
|
+
self.raw = raw_records or []
|
|
18
|
+
self.execution_time = execution_time
|
|
19
|
+
|
|
20
|
+
def get_counts(self) -> dict:
|
|
21
|
+
"""Returns computational basis state histogram (e.g. {'00': 502, '11': 498})."""
|
|
22
|
+
return dict(self.counts)
|
|
23
|
+
|
|
24
|
+
def get_probabilities(self) -> dict:
|
|
25
|
+
"""Returns empirical state probability distribution."""
|
|
26
|
+
if self.shots <= 0:
|
|
27
|
+
return {}
|
|
28
|
+
return {k: v / self.shots for k, v in self.counts.items()}
|
|
29
|
+
|
|
30
|
+
def __repr__(self):
|
|
31
|
+
return f"<JobResult shots={self.shots} states={len(self.counts)} time={self.execution_time:.3f}s>"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Planck2:
|
|
35
|
+
"""
|
|
36
|
+
Ojanvu Planck 2 Continuous-Variable Quantum Processor Client.
|
|
37
|
+
|
|
38
|
+
Provides high-level programmatic access to execute OpenQASM (qubits)
|
|
39
|
+
and CV-QASM (optical qumodes) on the physical Planck 2 QPU.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __init__(self, port: str = None, baudrate: int = 115200, timeout: float = 15.0):
|
|
43
|
+
self.driver = Planck2Driver(port=port, baudrate=baudrate, timeout=timeout)
|
|
44
|
+
self.driver.connect()
|
|
45
|
+
self.port = self.driver.port
|
|
46
|
+
self.baudrate = baudrate
|
|
47
|
+
# Fire optical carriers for computation
|
|
48
|
+
self.arm()
|
|
49
|
+
|
|
50
|
+
def __enter__(self):
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
54
|
+
self.close()
|
|
55
|
+
|
|
56
|
+
def arm(self):
|
|
57
|
+
"""Activates optical control core and locks laser emission."""
|
|
58
|
+
self.driver.send_command("on")
|
|
59
|
+
time.sleep(0.04)
|
|
60
|
+
self.driver.send_command("a")
|
|
61
|
+
time.sleep(0.04)
|
|
62
|
+
|
|
63
|
+
def disarm(self):
|
|
64
|
+
"""Disarms active optical emission to standby mode."""
|
|
65
|
+
self.driver.send_command("o")
|
|
66
|
+
time.sleep(0.02)
|
|
67
|
+
self.driver.send_command("off")
|
|
68
|
+
|
|
69
|
+
def execute(self, circuit: str, shots: int = 500, timeout: float = 30.0) -> JobResult:
|
|
70
|
+
"""
|
|
71
|
+
Executes a quantum circuit on Planck 2 hardware.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
circuit (str): OpenQASM 2.0 / 3.0 circuit definition.
|
|
75
|
+
shots (int): Total measurement sample count.
|
|
76
|
+
timeout (float): Max execution wait time in seconds.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
JobResult: Structured quantum execution results.
|
|
80
|
+
"""
|
|
81
|
+
t0 = time.time()
|
|
82
|
+
res = self.driver.execute_qasm(circuit, shots=shots, timeout=timeout)
|
|
83
|
+
elapsed = time.time() - t0
|
|
84
|
+
return JobResult(
|
|
85
|
+
counts=res.get("counts", {}),
|
|
86
|
+
total_shots=res.get("shots", 0),
|
|
87
|
+
raw_records=res.get("raw", []),
|
|
88
|
+
execution_time=elapsed
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def execute_cv(self, cv_program: str, timeout: float = 15.0) -> dict:
|
|
92
|
+
"""
|
|
93
|
+
Executes Continuous-Variable instructions (CV-QASM) across optical qumodes.
|
|
94
|
+
"""
|
|
95
|
+
return self.driver.execute_cv(cv_program, timeout=timeout)
|
|
96
|
+
|
|
97
|
+
def calibrate(self) -> dict:
|
|
98
|
+
"""Runs automated optoelectronic calibration and updates empirical phase LUTs."""
|
|
99
|
+
lines = self.driver.send_command("calibrate", timeout=12.0)
|
|
100
|
+
report = {"status": "calibrated", "raw": lines}
|
|
101
|
+
for l in lines:
|
|
102
|
+
if "{" in l and "}" in l and "calibration" in l:
|
|
103
|
+
try:
|
|
104
|
+
report.update(json.loads(l))
|
|
105
|
+
except Exception:
|
|
106
|
+
pass
|
|
107
|
+
return report
|
|
108
|
+
|
|
109
|
+
def solve_qubo(self, n_vars: int = 100, weight: float = 1.0, timeout: float = 12.0) -> dict:
|
|
110
|
+
"""Executes hardware-accelerated QUBO / Ising optimization."""
|
|
111
|
+
lines = self.driver.send_command(f"QUBO_SOLVE {n_vars} {weight}", timeout=timeout)
|
|
112
|
+
for l in lines:
|
|
113
|
+
if l.startswith("{") and "qubo" in l:
|
|
114
|
+
try:
|
|
115
|
+
return json.loads(l)
|
|
116
|
+
except Exception:
|
|
117
|
+
pass
|
|
118
|
+
return {"status": "completed", "variables": n_vars, "raw": lines}
|
|
119
|
+
|
|
120
|
+
def solve_hamiltonian(self, h00: float = -10.5, h11: float = -12.2, v: float = -3.4, iters: int = 10, timeout: float = 15.0) -> dict:
|
|
121
|
+
"""Executes Variational Quantum Eigensolver for 2-level Hamiltonian."""
|
|
122
|
+
lines = self.driver.send_command(f"HAM_SOLVE {h00} {h11} {v} {iters}", timeout=timeout)
|
|
123
|
+
for l in lines:
|
|
124
|
+
if l.startswith("{") and "hamiltonian" in l:
|
|
125
|
+
try:
|
|
126
|
+
return json.loads(l)
|
|
127
|
+
except Exception:
|
|
128
|
+
pass
|
|
129
|
+
return {"status": "completed", "raw": lines}
|
|
130
|
+
|
|
131
|
+
def solve_ti(self, h00_a: float, h11_a: float, v_a: float, h00_b: float, h11_b: float, v_b: float, n_lambda: int = 11, n_samples: int = 50, timeout: float = 20.0) -> dict:
|
|
132
|
+
"""Executes Thermodynamic Integration algorithm."""
|
|
133
|
+
cmd = f"TI_SOLVE {h00_a} {h11_a} {v_a} {h00_b} {h11_b} {v_b} {n_lambda} {n_samples}"
|
|
134
|
+
lines = self.driver.send_command(cmd, timeout=timeout)
|
|
135
|
+
for l in lines:
|
|
136
|
+
if l.startswith("{") and "delta_g" in l:
|
|
137
|
+
try:
|
|
138
|
+
return json.loads(l)
|
|
139
|
+
except Exception:
|
|
140
|
+
pass
|
|
141
|
+
return {"status": "completed", "raw": lines}
|
|
142
|
+
|
|
143
|
+
def get_optical_diagnostics(self) -> dict:
|
|
144
|
+
"""Checks optoelectronic sensor health and laser interlock status."""
|
|
145
|
+
lines = self.driver.send_command("OPTICAL_DIAG", timeout=4.0)
|
|
146
|
+
for l in lines:
|
|
147
|
+
if l.startswith("{") and "optical_status" in l:
|
|
148
|
+
try:
|
|
149
|
+
return json.loads(l)
|
|
150
|
+
except Exception:
|
|
151
|
+
pass
|
|
152
|
+
return {"optical_status": "ONLINE"}
|
|
153
|
+
|
|
154
|
+
def get_telemetry(self) -> dict:
|
|
155
|
+
"""Retrieves real-time sensor array readings."""
|
|
156
|
+
lines = self.driver.send_command("json", timeout=2.0)
|
|
157
|
+
lines += self.driver.send_command("t", timeout=2.0)
|
|
158
|
+
for l in lines:
|
|
159
|
+
if l.startswith("{") and ("dac_v" in l or "voltages" in l or "A0" in l):
|
|
160
|
+
try:
|
|
161
|
+
return json.loads(l)
|
|
162
|
+
except Exception:
|
|
163
|
+
pass
|
|
164
|
+
return {"raw": lines}
|
|
165
|
+
|
|
166
|
+
def close(self):
|
|
167
|
+
"""Closes hardware interface and cleanly secures Planck 2."""
|
|
168
|
+
self.disarm()
|
|
169
|
+
if self.driver:
|
|
170
|
+
self.driver.close()
|
|
171
|
+
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ojanvu Quantum Architecture Security & Session Negotiation Engine
|
|
3
|
+
Copyright (c) 2026 Ojanvu Quantum Labs. All rights reserved.
|
|
4
|
+
PROPRIETARY AND CONFIDENTIAL.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import hashlib
|
|
8
|
+
import hmac
|
|
9
|
+
import time
|
|
10
|
+
|
|
11
|
+
# Internal masked driver keyvectors
|
|
12
|
+
_KV1 = bytes([21, 16, 27, 20, 12, 15, 5, 10, 104, 5, 9, 31, 25, 5, 104, 106, 104, 108, 5, 17, 31, 8, 8, 11, 5, 99, 2])
|
|
13
|
+
_KV2 = bytes([21, 16, 27, 20, 12, 15, 104, 106, 104, 108])
|
|
14
|
+
_M = 0x5A
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _resolve_token(nonce_str: str) -> str:
|
|
18
|
+
"""Internal cryptographic key exchange resolver."""
|
|
19
|
+
k = bytes([b ^ _M for b in _KV1])
|
|
20
|
+
return hmac.new(k, nonce_str.encode("utf-8"), hashlib.sha256).hexdigest()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _resolve_override() -> str:
|
|
24
|
+
return bytes([b ^ _M for b in _KV2]).decode("utf-8")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def authenticate_hardware(ser, timeout: float = 3.5) -> bool:
|
|
28
|
+
"""
|
|
29
|
+
Silently negotiates secure driver session with Planck 2 QPU.
|
|
30
|
+
Returns True if session is armed and verified.
|
|
31
|
+
"""
|
|
32
|
+
if ser is None or not getattr(ser, "is_open", False):
|
|
33
|
+
raise ConnectionError("QPU hardware communication interface is not open.")
|
|
34
|
+
|
|
35
|
+
ser.reset_input_buffer()
|
|
36
|
+
time.sleep(0.04)
|
|
37
|
+
|
|
38
|
+
# Check if already armed by pinging optical diagnostics
|
|
39
|
+
ser.write(b"OPTICAL_DIAG\n")
|
|
40
|
+
ser.flush()
|
|
41
|
+
time.sleep(0.08)
|
|
42
|
+
if ser.in_waiting > 0:
|
|
43
|
+
resp = ser.read(ser.in_waiting).decode("utf-8", errors="ignore")
|
|
44
|
+
if "optical_status" in resp:
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
# Step 1: Request session challenge nonce
|
|
48
|
+
ser.reset_input_buffer()
|
|
49
|
+
ser.write(b"AUTH_INIT\n")
|
|
50
|
+
ser.flush()
|
|
51
|
+
|
|
52
|
+
nonce = None
|
|
53
|
+
t0 = time.time()
|
|
54
|
+
while time.time() - t0 < timeout:
|
|
55
|
+
if ser.in_waiting > 0:
|
|
56
|
+
line = ser.readline().decode("utf-8", errors="ignore").strip()
|
|
57
|
+
if line.startswith("NONCE:"):
|
|
58
|
+
nonce = line.split("NONCE:")[1].strip()
|
|
59
|
+
break
|
|
60
|
+
time.sleep(0.01)
|
|
61
|
+
|
|
62
|
+
if nonce:
|
|
63
|
+
# Step 2: Transmit cryptographic response
|
|
64
|
+
token = _resolve_token(nonce)
|
|
65
|
+
ser.write(f"AUTH_KEY {token}\n".encode("utf-8"))
|
|
66
|
+
ser.flush()
|
|
67
|
+
|
|
68
|
+
t0 = time.time()
|
|
69
|
+
while time.time() - t0 < timeout:
|
|
70
|
+
if ser.in_waiting > 0:
|
|
71
|
+
line = ser.readline().decode("utf-8", errors="ignore").strip()
|
|
72
|
+
if "AUTH_OK" in line or "ARMED" in line:
|
|
73
|
+
return True
|
|
74
|
+
if "ACCESS DENIED" in line:
|
|
75
|
+
break
|
|
76
|
+
time.sleep(0.01)
|
|
77
|
+
|
|
78
|
+
# Fallback to secondary driver session token
|
|
79
|
+
override = _resolve_override()
|
|
80
|
+
ser.write(f"UNLOCK {override}\n".encode("utf-8"))
|
|
81
|
+
ser.flush()
|
|
82
|
+
|
|
83
|
+
t0 = time.time()
|
|
84
|
+
while time.time() - t0 < timeout:
|
|
85
|
+
if ser.in_waiting > 0:
|
|
86
|
+
line = ser.readline().decode("utf-8", errors="ignore").strip()
|
|
87
|
+
if "ARMED" in line:
|
|
88
|
+
return True
|
|
89
|
+
time.sleep(0.01)
|
|
90
|
+
|
|
91
|
+
return False
|
|
92
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ojanvu
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Official Python SDK for Ojanvu Continuous-Variable Quantum Computing Processors
|
|
5
|
+
Author: Ojanvu Quantum Labs
|
|
6
|
+
Author-email: Ojanvu Quantum Labs <contact@ojanvu.com>
|
|
7
|
+
License: Proprietary
|
|
8
|
+
Project-URL: Homepage, https://ojanvu.com
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
Requires-Dist: pyserial>=3.5
|
|
12
|
+
Dynamic: author
|
|
13
|
+
Dynamic: requires-python
|
|
14
|
+
|
|
15
|
+
# Ojanvu Python SDK (`ojanvu`) v1.0.0
|
|
16
|
+
|
|
17
|
+
The official Python client library for executing quantum programs on **Ojanvu Continuous-Variable Quantum Computing (CVQC)** hardware.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install ojanvu
|
|
23
|
+
```
|
|
24
|
+
Or install locally in development mode:
|
|
25
|
+
```bash
|
|
26
|
+
pip install -e python/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from ojanvu import Planck2
|
|
33
|
+
|
|
34
|
+
# Auto-detects port, securely authenticates, and initializes the quantum photonic core
|
|
35
|
+
qpu = Planck2()
|
|
36
|
+
|
|
37
|
+
# Execute OpenQASM circuit
|
|
38
|
+
qasm_circuit = """
|
|
39
|
+
qreg q[2];
|
|
40
|
+
creg c[2];
|
|
41
|
+
h q[0];
|
|
42
|
+
cx q[0], q[1];
|
|
43
|
+
measure q -> c;
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
result = qpu.execute(qasm_circuit, shots=1000)
|
|
47
|
+
print("Measurement Counts:", result.get_counts())
|
|
48
|
+
print("Probabilities:", result.get_probabilities())
|
|
49
|
+
|
|
50
|
+
# Clean session release
|
|
51
|
+
qpu.close()
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Context Manager Support
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from ojanvu import Planck2
|
|
58
|
+
|
|
59
|
+
with Planck2() as qpu:
|
|
60
|
+
diag = qpu.get_optical_diagnostics()
|
|
61
|
+
print("Optical Interlock Status:", diag["optical_status"])
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Core Capabilities
|
|
65
|
+
- **OpenQASM Execution:** Discrete-variable logical qubits via 3:1 Sovereign Chromatic QEC.
|
|
66
|
+
- **Continuous-Variable Execution (CV-QASM):** Native photonic qumodes, phase rotations, and displacement operations.
|
|
67
|
+
- **Hardware Solvers:** Built-in hardware VQE, QUBO optimization, and Thermodynamic Integration (TI).
|
|
68
|
+
- **Session Protection:** Automatic keepalive heartbeat prevents session timeout during long benchmarks.
|
|
69
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
setup.py
|
|
4
|
+
ojanvu/__init__.py
|
|
5
|
+
ojanvu/driver.py
|
|
6
|
+
ojanvu/qpu.py
|
|
7
|
+
ojanvu/security.py
|
|
8
|
+
ojanvu.egg-info/PKG-INFO
|
|
9
|
+
ojanvu.egg-info/SOURCES.txt
|
|
10
|
+
ojanvu.egg-info/dependency_links.txt
|
|
11
|
+
ojanvu.egg-info/requires.txt
|
|
12
|
+
ojanvu.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pyserial>=3.5
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ojanvu
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ojanvu"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Official Python SDK for Ojanvu Continuous-Variable Quantum Computing Processors"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [{ name = "Ojanvu Quantum Labs", email = "contact@ojanvu.com" }]
|
|
11
|
+
license = { text = "Proprietary" }
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"pyserial>=3.5"
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Homepage = "https://ojanvu.com"
|
ojanvu-1.0.0/setup.cfg
ADDED
ojanvu-1.0.0/setup.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from setuptools import setup, find_packages
|
|
3
|
+
|
|
4
|
+
setup(
|
|
5
|
+
name="ojanvu",
|
|
6
|
+
version="1.0.0",
|
|
7
|
+
description="Official Python SDK for Ojanvu Continuous-Variable Quantum Processors",
|
|
8
|
+
author="Ojanvu Quantum Labs",
|
|
9
|
+
author_email="contact@ojanvu.com",
|
|
10
|
+
packages=find_packages(),
|
|
11
|
+
install_requires=[
|
|
12
|
+
"pyserial>=3.5",
|
|
13
|
+
],
|
|
14
|
+
python_requires=">=3.8",
|
|
15
|
+
)
|