qadence 1.5.1__py3-none-any.whl → 1.5.2__py3-none-any.whl
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.
- qadence/serial_expr_grammar.peg +11 -0
- qadence/serialization.py +190 -65
- qadence/utils.py +8 -2
- {qadence-1.5.1.dist-info → qadence-1.5.2.dist-info}/METADATA +31 -30
- {qadence-1.5.1.dist-info → qadence-1.5.2.dist-info}/RECORD +7 -6
- {qadence-1.5.1.dist-info → qadence-1.5.2.dist-info}/WHEEL +1 -1
- {qadence-1.5.1.dist-info → qadence-1.5.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
Program = expr EOF
|
2
|
+
expr = id '(' args ')'
|
3
|
+
args = (value / expr) (',' (value / expr))*
|
4
|
+
value = int / float_str / str / pair
|
5
|
+
pair = param '=' (int / bool / str)
|
6
|
+
param = r"[a-z][a-zA-Z]*"
|
7
|
+
id = r"[a-zA-Z][a-zA-Z_0-9]*"
|
8
|
+
bool = 'True' / 'False'
|
9
|
+
int = r"-?(0|[1-9][0-9]*)"
|
10
|
+
float_str = r"'-?(0|\d*(\.\d*))'"
|
11
|
+
str = r"'[a-zA-Z0-9\_\.]+'"
|
qadence/serialization.py
CHANGED
@@ -2,21 +2,26 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
import json
|
4
4
|
import os
|
5
|
+
import sys
|
6
|
+
from dataclasses import dataclass
|
7
|
+
from dataclasses import field as dataclass_field
|
8
|
+
from functools import lru_cache
|
5
9
|
from pathlib import Path
|
6
|
-
from typing import Any, get_args
|
10
|
+
from typing import Any, Callable, get_args
|
7
11
|
from typing import Union as TypingUnion
|
8
12
|
|
9
13
|
import torch
|
14
|
+
from arpeggio import NoMatch
|
15
|
+
from arpeggio.cleanpeg import ParserPEG
|
10
16
|
from sympy import *
|
11
|
-
from sympy import
|
17
|
+
from sympy import core, srepr
|
12
18
|
|
13
|
-
from qadence import QuantumCircuit, operations
|
19
|
+
from qadence import QuantumCircuit, operations, parameters
|
14
20
|
from qadence import blocks as qadenceblocks
|
15
21
|
from qadence.blocks import AbstractBlock
|
16
22
|
from qadence.blocks.utils import tag
|
17
23
|
from qadence.logger import get_logger
|
18
|
-
from qadence.
|
19
|
-
from qadence.models import QNN, QuantumModel
|
24
|
+
from qadence.models import QuantumModel
|
20
25
|
from qadence.parameters import Parameter
|
21
26
|
from qadence.register import Register
|
22
27
|
from qadence.types import SerializationFormat
|
@@ -43,27 +48,172 @@ SUPPORTED_OBJECTS = [
|
|
43
48
|
AbstractBlock,
|
44
49
|
QuantumCircuit,
|
45
50
|
QuantumModel,
|
46
|
-
QNN,
|
47
|
-
TransformedModule,
|
48
51
|
Register,
|
49
|
-
Basic,
|
52
|
+
core.Basic,
|
50
53
|
torch.nn.Module,
|
51
54
|
]
|
52
55
|
SUPPORTED_TYPES = TypingUnion[
|
53
56
|
AbstractBlock,
|
54
57
|
QuantumCircuit,
|
55
58
|
QuantumModel,
|
56
|
-
QNN,
|
57
|
-
TransformedModule,
|
58
59
|
Register,
|
59
|
-
Basic,
|
60
|
+
core.Basic,
|
60
61
|
torch.nn.Module,
|
61
62
|
]
|
62
63
|
|
63
|
-
|
64
64
|
ALL_BLOCK_NAMES = [
|
65
65
|
n for n in dir(qadenceblocks) if not (n.startswith("__") and n.endswith("__"))
|
66
66
|
] + [n for n in dir(operations) if not (n.startswith("__") and n.endswith("__"))]
|
67
|
+
SYMPY_EXPRS = [n for n in dir(core) if not (n.startswith("__") and n.endswith("__"))]
|
68
|
+
QADENCE_PARAMETERS = [n for n in dir(parameters) if not (n.startswith("__") and n.endswith("__"))]
|
69
|
+
|
70
|
+
|
71
|
+
THIS_PATH = Path(__file__).parent
|
72
|
+
GRAMMAR_FILE = THIS_PATH / "serial_expr_grammar.peg"
|
73
|
+
|
74
|
+
|
75
|
+
@lru_cache
|
76
|
+
def _parser_fn() -> ParserPEG:
|
77
|
+
with open(GRAMMAR_FILE, "r") as f:
|
78
|
+
grammar = f.read()
|
79
|
+
return ParserPEG(grammar, "Program")
|
80
|
+
|
81
|
+
|
82
|
+
_parsing_serialize_expr = _parser_fn()
|
83
|
+
|
84
|
+
|
85
|
+
def parse_expr_fn(code: str) -> bool:
|
86
|
+
"""
|
87
|
+
A parsing expressions function that checks whether a given code is valid on.
|
88
|
+
|
89
|
+
the parsing grammar. The grammar is defined to be compatible with `sympy`
|
90
|
+
expressions, such as `Float('-0.33261030434342942', precision=53)`, while
|
91
|
+
avoiding code injection such as `2*3` or `__import__('os').system('ls -la')`.
|
92
|
+
|
93
|
+
Args:
|
94
|
+
code (str): code to be parsed and checked.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
Boolean indicating whether the code matches the defined grammar or not.
|
98
|
+
"""
|
99
|
+
|
100
|
+
parser = _parsing_serialize_expr
|
101
|
+
try:
|
102
|
+
parser.parse(code)
|
103
|
+
except NoMatch:
|
104
|
+
return False
|
105
|
+
else:
|
106
|
+
return True
|
107
|
+
|
108
|
+
|
109
|
+
@dataclass
|
110
|
+
class SerializationModel:
|
111
|
+
"""
|
112
|
+
A serialization model class to serialize data from `QuantumModel`s,.
|
113
|
+
|
114
|
+
`torch.nn.Module` and similar structures. The data included in the
|
115
|
+
serialization logic includes: the `AbstractBlock` and its children
|
116
|
+
classes, `QuantumCircuit`, `Register`, and `sympy` expressions
|
117
|
+
(including `Parameter` class from `qadence.parameters`).
|
118
|
+
|
119
|
+
A children class must define the `value` attribute type and how to
|
120
|
+
handle it, since it is the main property for the class to be used
|
121
|
+
by the serialization process. For instance:
|
122
|
+
|
123
|
+
```python
|
124
|
+
@dataclass
|
125
|
+
class QuantumCircuitSerialization(SerializationModel):
|
126
|
+
value: QuantumCircuit = dataclass_field(init=False)
|
127
|
+
|
128
|
+
def __post_init__(self) -> None:
|
129
|
+
self.value = (
|
130
|
+
QuantumCircuit._from_dict(self.d)
|
131
|
+
if isinstance(self.d, dict)
|
132
|
+
else self.d
|
133
|
+
)
|
134
|
+
```
|
135
|
+
"""
|
136
|
+
|
137
|
+
d: dict = dataclass_field(default_factory=dict)
|
138
|
+
value: Any = dataclass_field(init=False)
|
139
|
+
|
140
|
+
|
141
|
+
@dataclass
|
142
|
+
class BlockTypeSerialization(SerializationModel):
|
143
|
+
value: AbstractBlock = dataclass_field(init=False)
|
144
|
+
|
145
|
+
def __post_init__(self) -> None:
|
146
|
+
block = (
|
147
|
+
getattr(operations, self.d["type"])
|
148
|
+
if hasattr(operations, self.d["type"])
|
149
|
+
else getattr(qadenceblocks, self.d["type"])
|
150
|
+
)._from_dict(self.d)
|
151
|
+
if self.d["tag"] is not None:
|
152
|
+
block = tag(block, self.d["tag"])
|
153
|
+
self.value = block
|
154
|
+
|
155
|
+
|
156
|
+
@dataclass
|
157
|
+
class QuantumCircuitSerialization(SerializationModel):
|
158
|
+
value: QuantumCircuit = dataclass_field(init=False)
|
159
|
+
|
160
|
+
def __post_init__(self) -> None:
|
161
|
+
self.value = QuantumCircuit._from_dict(self.d) if isinstance(self.d, dict) else self.d
|
162
|
+
|
163
|
+
|
164
|
+
@dataclass
|
165
|
+
class RegisterSerialization(SerializationModel):
|
166
|
+
value: Register = dataclass_field(init=False)
|
167
|
+
|
168
|
+
def __post_init__(self) -> None:
|
169
|
+
self.value = Register._from_dict(self.d)
|
170
|
+
|
171
|
+
|
172
|
+
@dataclass
|
173
|
+
class ModelSerialization(SerializationModel):
|
174
|
+
as_torch: bool = False
|
175
|
+
value: torch.nn.Module = dataclass_field(init=False)
|
176
|
+
|
177
|
+
def __post_init__(self) -> None:
|
178
|
+
module_name = list(self.d.keys())[0]
|
179
|
+
obj = globals().get(module_name, None)
|
180
|
+
if obj is None:
|
181
|
+
obj = self._resolve_module(module_name)
|
182
|
+
if hasattr(obj, "_from_dict"):
|
183
|
+
self.value = obj._from_dict(self.d, self.as_torch)
|
184
|
+
elif hasattr(obj, "load_state_dict"):
|
185
|
+
self.value = obj.load_state_dict(self.d[module_name])
|
186
|
+
else:
|
187
|
+
msg = (
|
188
|
+
f"Unable to deserialize object '{module_name}'. "
|
189
|
+
f"Supported types are {SUPPORTED_OBJECTS}."
|
190
|
+
)
|
191
|
+
logger.error(TypeError(msg))
|
192
|
+
raise TypeError(msg)
|
193
|
+
|
194
|
+
@staticmethod
|
195
|
+
def _resolve_module(module: str) -> Any:
|
196
|
+
for loaded_module in sys.modules.keys():
|
197
|
+
if "qadence" in loaded_module:
|
198
|
+
obj = getattr(sys.modules[loaded_module], module, None)
|
199
|
+
if obj:
|
200
|
+
return obj
|
201
|
+
raise ValueError(f"Couldn't resolve module '{module}'.")
|
202
|
+
|
203
|
+
|
204
|
+
@dataclass
|
205
|
+
class ExpressionSerialization(SerializationModel):
|
206
|
+
value: str | core.Expr | float = dataclass_field(init=False)
|
207
|
+
|
208
|
+
def __post_init__(self) -> None:
|
209
|
+
if parse_expr_fn(self.d["expression"]):
|
210
|
+
expr = eval(self.d["expression"])
|
211
|
+
if hasattr(expr, "free_symbols"):
|
212
|
+
for s in expr.free_symbols:
|
213
|
+
s.value = float(self.d["symbols"][s.name]["value"])
|
214
|
+
self.value = expr
|
215
|
+
else:
|
216
|
+
raise ValueError(f"Invalid expression: {self.d['expression']}")
|
67
217
|
|
68
218
|
|
69
219
|
def save_pt(d: dict, file_path: str | Path) -> None:
|
@@ -94,11 +244,11 @@ def serialize(obj: SUPPORTED_TYPES, save_params: bool = False) -> dict:
|
|
94
244
|
"""
|
95
245
|
Supported Types:
|
96
246
|
|
97
|
-
AbstractBlock | QuantumCircuit | QuantumModel |
|
247
|
+
AbstractBlock | QuantumCircuit | QuantumModel | torch.nn.Module | Register | Module
|
98
248
|
Serializes a qadence object to a dictionary.
|
99
249
|
|
100
250
|
Arguments:
|
101
|
-
obj (AbstractBlock | QuantumCircuit | QuantumModel | Register | Module):
|
251
|
+
obj (AbstractBlock | QuantumCircuit | QuantumModel | Register | torch.nn.Module):
|
102
252
|
Returns:
|
103
253
|
A dict.
|
104
254
|
|
@@ -132,21 +282,28 @@ def serialize(obj: SUPPORTED_TYPES, save_params: bool = False) -> dict:
|
|
132
282
|
"""
|
133
283
|
if not isinstance(obj, get_args(SUPPORTED_TYPES)):
|
134
284
|
logger.error(TypeError(f"Serialization of object type {type(obj)} not supported."))
|
135
|
-
|
285
|
+
|
286
|
+
d: dict = dict()
|
136
287
|
try:
|
137
|
-
if isinstance(obj, Expr):
|
138
|
-
symb_dict =
|
288
|
+
if isinstance(obj, core.Expr):
|
289
|
+
symb_dict = dict()
|
139
290
|
expr_dict = {"name": str(obj), "expression": srepr(obj)}
|
140
|
-
symbs: set[Parameter | Basic] = obj.free_symbols
|
291
|
+
symbs: set[Parameter | core.Basic] = obj.free_symbols
|
141
292
|
if symbs:
|
142
293
|
symb_dict = {"symbols": {str(s): s._to_dict() for s in symbs}}
|
143
294
|
d = {**expr_dict, **symb_dict}
|
144
|
-
elif isinstance(obj, (QuantumModel, QNN, TransformedModule)):
|
145
|
-
d = obj._to_dict(save_params)
|
146
|
-
elif isinstance(obj, torch.nn.Module):
|
147
|
-
d = {type(obj).__name__: obj.state_dict()}
|
148
295
|
else:
|
149
|
-
|
296
|
+
if hasattr(obj, "_to_dict"):
|
297
|
+
model_to_dict: Callable = obj._to_dict
|
298
|
+
d = (
|
299
|
+
model_to_dict(save_params)
|
300
|
+
if isinstance(obj, torch.nn.Module)
|
301
|
+
else model_to_dict()
|
302
|
+
)
|
303
|
+
elif hasattr(obj, "state_dict"):
|
304
|
+
d = {type(obj).__name__: obj.state_dict()}
|
305
|
+
else:
|
306
|
+
raise ValueError(f"Cannot serialize object {obj}.")
|
150
307
|
except Exception as e:
|
151
308
|
logger.error(f"Serialization of object {obj} failed due to {e}")
|
152
309
|
return d
|
@@ -156,13 +313,14 @@ def deserialize(d: dict, as_torch: bool = False) -> SUPPORTED_TYPES:
|
|
156
313
|
"""
|
157
314
|
Supported Types:
|
158
315
|
|
159
|
-
AbstractBlock | QuantumCircuit | QuantumModel |
|
316
|
+
AbstractBlock | QuantumCircuit | QuantumModel | Register | torch.nn.Module
|
160
317
|
Deserializes a dict to one of the supported types.
|
161
318
|
|
162
319
|
Arguments:
|
163
320
|
d (dict): A dict containing a serialized object.
|
321
|
+
as_torch (bool): Whether to transform to torch for the deserialized object.
|
164
322
|
Returns:
|
165
|
-
AbstractBlock, QuantumCircuit, QuantumModel,
|
323
|
+
AbstractBlock, QuantumCircuit, QuantumModel, Register, torch.nn.Module.
|
166
324
|
|
167
325
|
Examples:
|
168
326
|
```python exec="on" source="material-block" result="json"
|
@@ -192,51 +350,18 @@ def deserialize(d: dict, as_torch: bool = False) -> SUPPORTED_TYPES:
|
|
192
350
|
assert torch.isclose(qm.expectation({}), qm_deserialized.expectation({}))
|
193
351
|
```
|
194
352
|
"""
|
195
|
-
obj:
|
353
|
+
obj: SerializationModel
|
196
354
|
if d.get("expression"):
|
197
|
-
|
198
|
-
if hasattr(expr, "free_symbols"):
|
199
|
-
for symb in expr.free_symbols:
|
200
|
-
symb.value = float(d["symbols"][symb.name]["value"])
|
201
|
-
obj = expr
|
202
|
-
elif d.get("QuantumModel"):
|
203
|
-
obj = QuantumModel._from_dict(d, as_torch)
|
204
|
-
elif d.get("QNN"):
|
205
|
-
obj = QNN._from_dict(d, as_torch)
|
206
|
-
elif d.get("TransformedModule"):
|
207
|
-
obj = TransformedModule._from_dict(d, as_torch)
|
355
|
+
obj = ExpressionSerialization(d)
|
208
356
|
elif d.get("block") and d.get("register"):
|
209
|
-
obj =
|
357
|
+
obj = QuantumCircuitSerialization(d)
|
210
358
|
elif d.get("graph"):
|
211
|
-
obj =
|
359
|
+
obj = RegisterSerialization(d)
|
212
360
|
elif d.get("type"):
|
213
|
-
|
214
|
-
block: AbstractBlock = (
|
215
|
-
getattr(operations, d["type"])._from_dict(d)
|
216
|
-
if hasattr(operations, d["type"])
|
217
|
-
else getattr(qadenceblocks, d["type"])._from_dict(d)
|
218
|
-
)
|
219
|
-
if d["tag"] is not None:
|
220
|
-
block = tag(block, d["tag"])
|
221
|
-
obj = block
|
361
|
+
obj = BlockTypeSerialization(d)
|
222
362
|
else:
|
223
|
-
|
224
|
-
|
225
|
-
msg = warnings.warn(
|
226
|
-
"In order to load a custom torch.nn.Module, make sure its imported in the namespace."
|
227
|
-
)
|
228
|
-
try:
|
229
|
-
module_name = list(d.keys())[0]
|
230
|
-
obj = getattr(globals(), module_name)
|
231
|
-
obj.load_state_dict(d[module_name])
|
232
|
-
except Exception as e:
|
233
|
-
logger.error(
|
234
|
-
TypeError(
|
235
|
-
f"{msg}. Unable to deserialize object due to {e}.\
|
236
|
-
Supported objects are: {SUPPORTED_OBJECTS}"
|
237
|
-
)
|
238
|
-
)
|
239
|
-
return obj
|
363
|
+
obj = ModelSerialization(d, as_torch=as_torch)
|
364
|
+
return obj.value
|
240
365
|
|
241
366
|
|
242
367
|
def save(
|
qadence/utils.py
CHANGED
@@ -154,11 +154,17 @@ def format_number(x: float | complex, num_digits: int = 3) -> str:
|
|
154
154
|
raise ValueError(f"Unknown number type: {type(x)}")
|
155
155
|
|
156
156
|
|
157
|
-
def format_parameter(p: sympy.Basic) -> str:
|
157
|
+
def format_parameter(p: sympy.Basic, num_digits: int = 3) -> str:
|
158
|
+
"""Format numerical values within a sympy expression."""
|
159
|
+
|
158
160
|
def round_expr(expr: sympy.Basic, num_digits: int) -> sympy.Basic:
|
159
161
|
return expr.xreplace({n: round(n, num_digits) for n in expr.atoms(sympy.Number)})
|
160
162
|
|
161
|
-
|
163
|
+
expr = round_expr(p, num_digits)
|
164
|
+
conv_str = str(expr)
|
165
|
+
if expr.is_real and len(conv_str) > num_digits + 2:
|
166
|
+
conv_str = conv_str[0 : num_digits + 2]
|
167
|
+
return conv_str
|
162
168
|
|
163
169
|
|
164
170
|
def print_sympy_expr(expr: sympy.Expr, num_digits: int = 3) -> str:
|
@@ -1,8 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: qadence
|
3
|
-
Version: 1.5.
|
3
|
+
Version: 1.5.2
|
4
4
|
Summary: Pasqal interface for circuit-based quantum computing SDKs
|
5
|
-
Author-email: Aleksander Wennersteen <aleksander.wennersteen@pasqal.com>, Gert-Jan Both <gert-jan.both@pasqal.com>, Niklas Heim <niklas.heim@pasqal.com>, Mario Dagrada <mario.dagrada@pasqal.com>, Vincent Elfving <vincent.elfving@pasqal.com>, Dominik Seitz <dominik.seitz@pasqal.com>, Roland Guichard <roland.guichard@pasqal.com>, "Joao P. Moutinho" <joao.moutinho@pasqal.com>, Vytautas Abramavicius <vytautas.abramavicius@pasqal.com>, Gergana Velikova <gergana.velikova@pasqal.com>
|
5
|
+
Author-email: Aleksander Wennersteen <aleksander.wennersteen@pasqal.com>, Gert-Jan Both <gert-jan.both@pasqal.com>, Niklas Heim <niklas.heim@pasqal.com>, Mario Dagrada <mario.dagrada@pasqal.com>, Vincent Elfving <vincent.elfving@pasqal.com>, Dominik Seitz <dominik.seitz@pasqal.com>, Roland Guichard <roland.guichard@pasqal.com>, "Joao P. Moutinho" <joao.moutinho@pasqal.com>, Vytautas Abramavicius <vytautas.abramavicius@pasqal.com>, Gergana Velikova <gergana.velikova@pasqal.com>, Eduardo Maschio <eduardo.maschio@pasqal.com>
|
6
6
|
License: Apache 2.0
|
7
7
|
License-File: LICENSE
|
8
8
|
Classifier: License :: OSI Approved :: Apache Software License
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
14
14
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
15
15
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
16
16
|
Requires-Python: <3.13,>=3.9
|
17
|
+
Requires-Dist: arpeggio==2.0.2
|
17
18
|
Requires-Dist: deepdiff
|
18
19
|
Requires-Dist: jsonschema
|
19
20
|
Requires-Dist: matplotlib
|
@@ -27,7 +28,7 @@ Requires-Dist: sympytorch>=0.1.2
|
|
27
28
|
Requires-Dist: tensorboard>=2.12.0
|
28
29
|
Requires-Dist: torch
|
29
30
|
Provides-Extra: all
|
30
|
-
Requires-Dist: amazon-braket-sdk; extra == 'all'
|
31
|
+
Requires-Dist: amazon-braket-sdk==1.71.0; extra == 'all'
|
31
32
|
Requires-Dist: graphviz; extra == 'all'
|
32
33
|
Requires-Dist: libs; extra == 'all'
|
33
34
|
Requires-Dist: protocols; extra == 'all'
|
@@ -53,19 +54,21 @@ Provides-Extra: visualization
|
|
53
54
|
Requires-Dist: graphviz; extra == 'visualization'
|
54
55
|
Description-Content-Type: text/markdown
|
55
56
|
|
56
|
-
<
|
57
|
-
<
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
<p align="center">
|
58
|
+
<picture>
|
59
|
+
<source media="(prefers-color-scheme: dark)" srcset="./docs/extras/assets/logo/qadence_logo_white.svg" width="75%">
|
60
|
+
<source media="(prefers-color-scheme: light)" srcset="./docs/extras/assets/logo/qadence_logo.svg" width="75%">
|
61
|
+
<img alt="Qadence logo" src="./docs/assets/logo/qadence_logo.svg" width="75%">
|
62
|
+
</picture>
|
63
|
+
</p>
|
64
|
+
|
65
|
+
**Qadence** is a Python package that provides a simple interface to build **digital-analog quantum
|
66
|
+
programs** with tunable qubit interactions and arbitrary register topologies realizable on neutral atom devices.
|
61
67
|
|
62
68
|
**For a high-level overview of Qadence features, [check out our white paper](https://arxiv.org/abs/2401.09915).**
|
63
69
|
|
64
70
|
**For more detailed information, [check out the documentation](https://pasqal-io.github.io/qadence/latest/).**
|
65
71
|
|
66
|
-
**Qadence** is a Python package that provides a simple interface to build _**digital-analog quantum
|
67
|
-
programs**_ with tunable qubit interaction defined on _**arbitrary register topologies**_ realizable on neutral atom devices.
|
68
|
-
|
69
72
|
[](https://github.com/pasqal-io/qadence/actions/workflows/lint.yml)
|
70
73
|
[](https://github.com/pasqal-io/qadence/actions/workflows/test_fast.yml)
|
71
74
|
[](https://pasqal-io.github.io/qadence/latest)
|
@@ -74,27 +77,26 @@ programs**_ with tunable qubit interaction defined on _**arbitrary register topo
|
|
74
77
|
|
75
78
|
## Feature highlights
|
76
79
|
|
77
|
-
<
|
78
|
-
<
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
80
|
+
<p align="center">
|
81
|
+
<picture>
|
82
|
+
<source media="(prefers-color-scheme: dark)" srcset="./docs/extras/assets/qadence_arch.svg" width="75%">
|
83
|
+
<source media="(prefers-color-scheme: light)" srcset="./docs/extras/assets/qadence_arch.svg" width="75%">
|
84
|
+
<img alt="Qadence architecture" src="./docs/assets/qadence_arch.svg" width="75%">
|
85
|
+
</picture>
|
86
|
+
<p align="center">
|
83
87
|
|
84
|
-
* A [block-based system](docs/
|
88
|
+
* A [block-based system](docs/content/block_system.md) for composing _**complex digital-analog
|
85
89
|
programs**_ in a flexible and scalable manner, inspired by the Julia quantum SDK
|
86
90
|
[Yao.jl](https://github.com/QuantumBFS/Yao.jl) and functional programming concepts.
|
87
91
|
|
88
|
-
*
|
89
|
-
using [arbitrary registers topologies](docs/tutorials/register.md).
|
90
|
-
|
91
|
-
* An intuitive [expression-based system](docs/tutorials/parameters.md) developed on top of the symbolic library [Sympy](https://www.sympy.org/en/index.html) to construct _**parametric quantum programs**_ easily.
|
92
|
-
|
93
|
-
* [High-order generalized parameter shift rules](docs/advanced_tutorials/differentiability.md) for _**differentiating parametrized quantum operations**_.
|
92
|
+
* An intuitive [expression-based system](docs/content/parameters.md) developed on top of the symbolic library [Sympy](https://www.sympy.org/en/index.html) to construct _**parametric quantum programs**_ easily.
|
94
93
|
|
95
94
|
* Out-of-the-box _**automatic differentiability**_ of quantum programs with [PyTorch](https://pytorch.org/) integration.
|
96
95
|
|
97
|
-
*
|
96
|
+
* [High-order generalized parameter shift rules](docs/tutorials/advanced_tutorials/differentiability.md) for _**differentiating parametrized quantum operations**_.
|
97
|
+
|
98
|
+
* A [simple interface](docs/tutorials/digital_analog_qc/analog-basics.md) to work with _**interacting neutral-atom qubit systems**_
|
99
|
+
using [arbitrary registers topologies](docs/content/register.md).
|
98
100
|
|
99
101
|
## Installation guide
|
100
102
|
|
@@ -106,11 +108,10 @@ pip install qadence
|
|
106
108
|
|
107
109
|
The default, pre-installed backend for Qadence is [PyQTorch](https://github.com/pasqal-io/pyqtorch), a differentiable state vector simulator for digital-analog simulation based on `PyTorch`. It is possible to install additional, `PyTorch` -based backends and the circuit visualization library using the following extras:
|
108
110
|
|
109
|
-
* `pulser`: The [Pulser](https://github.com/pasqal-io/Pulser) backend for composing, simulating and executing pulse sequences for neutral-atom quantum devices.
|
110
|
-
* `braket`: The [Braket](https://github.com/amazon-braket/amazon-braket-sdk-python) backend, an open source library that provides a framework for interacting with quantum computing hardware devices through Amazon Braket.
|
111
111
|
* `visualization`: A visualization library to display quantum circuit diagrams.
|
112
112
|
* `protocols`: A collection of [protocols](https://github.com/pasqal-io/qadence-protocols) for error mitigation in Qadence.
|
113
113
|
* `libs`: A collection of [functionalities](https://github.com/pasqal-io/qadence-libs) for graph machine learning problems build on top of Qadence.
|
114
|
+
* `pulser`: The [Pulser](https://github.com/pasqal-io/Pulser) backend for composing, simulating and executing pulse sequences for neutral-atom quantum devices (experimental).
|
114
115
|
|
115
116
|
Qadence also supports a `JAX` engine which is currently supporting the [Horqrux](https://github.com/pasqal-io/horqrux) backend. `horqrux` is currently only available via the [low-level API](examples/backends/low_level/horqrux_backend.py).
|
116
117
|
|
@@ -118,7 +119,7 @@ Qadence also supports a `JAX` engine which is currently supporting the [Horqrux]
|
|
118
119
|
To install individual extras, use the following syntax (**IMPORTANT** Make sure to use quotes):
|
119
120
|
|
120
121
|
```bash
|
121
|
-
pip install "qadence[
|
122
|
+
pip install "qadence[pulser,visualization]"
|
122
123
|
```
|
123
124
|
|
124
125
|
To install all available extras, simply do:
|
@@ -144,10 +145,10 @@ conda install python-graphviz
|
|
144
145
|
|
145
146
|
## Contributing
|
146
147
|
|
147
|
-
Before making a contribution, please review our [code of conduct](docs/CODE_OF_CONDUCT.md).
|
148
|
+
Before making a contribution, please review our [code of conduct](docs/getting_started/CODE_OF_CONDUCT.md).
|
148
149
|
|
149
150
|
- **Submitting Issues:** To submit bug reports or feature requests, please use our [issue tracker](https://github.com/pasqal-io/qadence/issues).
|
150
|
-
- **Developing in qadence:** To learn more about how to develop within `qadence`, please refer to [contributing guidelines](docs/CONTRIBUTING.md).
|
151
|
+
- **Developing in qadence:** To learn more about how to develop within `qadence`, please refer to [contributing guidelines](docs/getting_started/CONTRIBUTING.md).
|
151
152
|
|
152
153
|
### Setting up qadence in development mode
|
153
154
|
|
@@ -14,10 +14,11 @@ qadence/protocols.py,sha256=bcYTxSjgMPV-a-D6yv90jCpnGik8myzaNpFv9z1gzJ0,442
|
|
14
14
|
qadence/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
qadence/qubit_support.py,sha256=Nkn1Q01RVViTcggSIom7EFKdWpAuM4TMGwBZ5feCUxA,2120
|
16
16
|
qadence/register.py,sha256=cBMzwZ7GWZ5ieuFt0bpproEI6a2ncNwfjj7ic379zyg,10276
|
17
|
-
qadence/
|
17
|
+
qadence/serial_expr_grammar.peg,sha256=z5ytL7do9kO8o4h-V5GrsDuLdso0KsRcMuIYURFfmAY,328
|
18
|
+
qadence/serialization.py,sha256=ra6oBB2KPDj0BlAL2fWqOSce9IBCfZuSKgFlh0Zjv-A,15695
|
18
19
|
qadence/states.py,sha256=_J__vZuDPsKqKDFSCfgWxSNY2Ho6cCqTHjJ9-gMtd8M,14341
|
19
20
|
qadence/types.py,sha256=cA3L3hlPW320_03n8_weCuAUXmDX5Jq3puawtkgOK7s,9699
|
20
|
-
qadence/utils.py,sha256=
|
21
|
+
qadence/utils.py,sha256=tSLXSt8pC1Oixs3gmgkAkHYG9MEH_Dfzyt6uxYfWhwg,9065
|
21
22
|
qadence/analog/__init__.py,sha256=BCyS9R4KUjzUXN0Ax3b0eMo8ZAuSkGoJQVtZ4_pvAFs,279
|
22
23
|
qadence/analog/addressing.py,sha256=fu5-xW9lquEbagApNp23S_ET1kl0iDtZUrIYSVNmw9s,6435
|
23
24
|
qadence/analog/constants.py,sha256=B2phQoN1ASL8CwM-Dsa1rbraYwGwwPSeiB3HbVe-MPA,1243
|
@@ -134,7 +135,7 @@ qadence/transpile/digitalize.py,sha256=iWRwYAYQsD2INHj0HNbGJriv_3fRCuBW1nDBrwtKS
|
|
134
135
|
qadence/transpile/flatten.py,sha256=EdhSG5WyF56nbnxINNLqrHgY84MRM1YFjT3fR4aph5Q,3427
|
135
136
|
qadence/transpile/invert.py,sha256=KAefHTG2AWr39aengVhXrzCtJPhrZC-ZnL6vYvmbnY0,4867
|
136
137
|
qadence/transpile/transpile.py,sha256=6MRRkk1OS279L1fwUQjazA6qlfpbd-T_EJMKT8hAhOU,2721
|
137
|
-
qadence-1.5.
|
138
|
-
qadence-1.5.
|
139
|
-
qadence-1.5.
|
140
|
-
qadence-1.5.
|
138
|
+
qadence-1.5.2.dist-info/METADATA,sha256=19euItyRCLcNIYDi0bnc0RRw4eJBL7_zFAI6A7aW9xo,8931
|
139
|
+
qadence-1.5.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
140
|
+
qadence-1.5.2.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
141
|
+
qadence-1.5.2.dist-info/RECORD,,
|
File without changes
|