emu-base 2.4.2__py3-none-any.whl → 2.4.4__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.
- emu_base/__init__.py +3 -2
- emu_base/jump_lindblad_operators.py +56 -24
- emu_base/pulser_adapter.py +11 -3
- emu_base/utils.py +21 -0
- {emu_base-2.4.2.dist-info → emu_base-2.4.4.dist-info}/METADATA +1 -1
- {emu_base-2.4.2.dist-info → emu_base-2.4.4.dist-info}/RECORD +7 -7
- {emu_base-2.4.2.dist-info → emu_base-2.4.4.dist-info}/WHEEL +0 -0
emu_base/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@ from .math.brents_root_finding import find_root_brents
|
|
|
4
4
|
from .math.krylov_exp import krylov_exp, DEFAULT_MAX_KRYLOV_DIM
|
|
5
5
|
from .jump_lindblad_operators import compute_noise_from_lindbladians
|
|
6
6
|
from .math.matmul import matmul_2x2_with_batched
|
|
7
|
-
from .utils import get_max_rss, apply_measurement_errors, unix_like
|
|
7
|
+
from .utils import get_max_rss, apply_measurement_errors, unix_like, init_logging
|
|
8
8
|
|
|
9
9
|
__all__ = [
|
|
10
10
|
"__version__",
|
|
@@ -19,6 +19,7 @@ __all__ = [
|
|
|
19
19
|
"DEVICE_COUNT",
|
|
20
20
|
"apply_measurement_errors",
|
|
21
21
|
"unix_like",
|
|
22
|
+
"init_logging",
|
|
22
23
|
]
|
|
23
24
|
|
|
24
|
-
__version__ = "2.4.
|
|
25
|
+
__version__ = "2.4.4"
|
|
@@ -2,59 +2,91 @@ from pulser.noise_model import NoiseModel
|
|
|
2
2
|
import torch
|
|
3
3
|
import math
|
|
4
4
|
|
|
5
|
+
dtype = torch.complex128
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
def get_lindblad_operators(
|
|
7
|
-
*,
|
|
9
|
+
*,
|
|
10
|
+
noise_type: str,
|
|
11
|
+
noise_model: NoiseModel,
|
|
12
|
+
interact_type: str = "ising",
|
|
13
|
+
dim: int = 2,
|
|
8
14
|
) -> list[torch.Tensor]:
|
|
15
|
+
|
|
9
16
|
assert noise_type in noise_model.noise_types
|
|
10
17
|
|
|
11
18
|
if noise_type == "relaxation":
|
|
12
19
|
c = math.sqrt(noise_model.relaxation_rate)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
]
|
|
20
|
+
relaxation = torch.zeros(dim, dim, dtype=dtype)
|
|
21
|
+
relaxation[0, 1] = c
|
|
22
|
+
return [relaxation]
|
|
16
23
|
|
|
17
24
|
if noise_type == "dephasing":
|
|
18
25
|
if noise_model.hyperfine_dephasing_rate != 0.0:
|
|
19
26
|
raise NotImplementedError("hyperfine_dephasing_rate is unsupported")
|
|
20
27
|
|
|
21
28
|
c = math.sqrt(noise_model.dephasing_rate / 2)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
]
|
|
29
|
+
dephasing = torch.zeros(dim, dim, dtype=dtype)
|
|
30
|
+
|
|
31
|
+
dephasing[0, 0] = c
|
|
32
|
+
dephasing[1, 1] = -c
|
|
33
|
+
|
|
34
|
+
return [dephasing]
|
|
25
35
|
|
|
26
36
|
if noise_type == "depolarizing":
|
|
27
37
|
c = math.sqrt(noise_model.depolarizing_rate / 4)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
depolarizing_x = torch.zeros(dim, dim, dtype=dtype)
|
|
39
|
+
depolarizing_x[0, 1] = c
|
|
40
|
+
depolarizing_x[1, 0] = c
|
|
41
|
+
|
|
42
|
+
depolarizing_y = torch.zeros(dim, dim, dtype=dtype)
|
|
43
|
+
depolarizing_y[0, 1] = torch.tensor(-c * 1.0j, dtype=dtype)
|
|
44
|
+
depolarizing_y[1, 0] = torch.tensor(c * 1.0j, dtype=dtype)
|
|
45
|
+
|
|
46
|
+
depolarizing_z = torch.zeros(dim, dim, dtype=dtype)
|
|
47
|
+
depolarizing_z[0, 0] = c
|
|
48
|
+
depolarizing_z[1, 1] = -c
|
|
49
|
+
|
|
50
|
+
return [depolarizing_x, depolarizing_y, depolarizing_z]
|
|
33
51
|
|
|
34
52
|
if noise_type == "eff_noise":
|
|
35
53
|
if not all(
|
|
36
|
-
isinstance(op, torch.Tensor) and op.shape == (
|
|
54
|
+
isinstance(op, torch.Tensor) and op.shape == (dim, dim)
|
|
37
55
|
for op in noise_model.eff_noise_opers
|
|
38
56
|
):
|
|
39
|
-
raise ValueError(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
57
|
+
raise ValueError(
|
|
58
|
+
"Only 2 by 2 or 3 by 3 effective noise operator matrices are "
|
|
59
|
+
"supported and it should be given as torch tensors "
|
|
60
|
+
)
|
|
61
|
+
if interact_type == "ising":
|
|
62
|
+
return [ # lindblad operators in pulser ising basis
|
|
63
|
+
math.sqrt(rate) * torch.flip(torch.as_tensor(op), (0, 1))
|
|
64
|
+
for rate, op in zip(
|
|
65
|
+
noise_model.eff_noise_rates, noise_model.eff_noise_opers
|
|
66
|
+
)
|
|
67
|
+
]
|
|
68
|
+
elif interact_type == "XY":
|
|
69
|
+
return [ # lindblad operators in pulser XY basis
|
|
70
|
+
math.sqrt(rate) * torch.as_tensor(op)
|
|
71
|
+
for rate, op in zip(
|
|
72
|
+
noise_model.eff_noise_rates, noise_model.eff_noise_opers
|
|
73
|
+
)
|
|
74
|
+
]
|
|
46
75
|
|
|
47
76
|
raise ValueError(f"Unknown noise type: {noise_type}")
|
|
48
77
|
|
|
49
78
|
|
|
50
|
-
def compute_noise_from_lindbladians(
|
|
79
|
+
def compute_noise_from_lindbladians(
|
|
80
|
+
lindbladians: list[torch.Tensor], dim: int = 2
|
|
81
|
+
) -> torch.Tensor:
|
|
51
82
|
"""
|
|
52
|
-
Compute the single-qubit Hamiltonian noise term -0.5i∑L†L from all the
|
|
83
|
+
Compute the single-qubit Hamiltonian noise term -0.5i∑L†L from all the
|
|
84
|
+
given lindbladians.
|
|
53
85
|
"""
|
|
54
86
|
assert all(
|
|
55
|
-
lindbladian.shape == (
|
|
87
|
+
lindbladian.shape == (dim, dim) for lindbladian in lindbladians
|
|
56
88
|
), "Only single-qubit lindblad operators are supported"
|
|
57
89
|
|
|
58
|
-
zero = torch.zeros(
|
|
90
|
+
zero = torch.zeros(dim, dim, dtype=dtype)
|
|
59
91
|
|
|
60
92
|
return -0.5j * sum((L.mH @ L for L in lindbladians), start=zero)
|
emu_base/pulser_adapter.py
CHANGED
|
@@ -20,7 +20,7 @@ _NON_LINDBLADIAN_NOISE = {"SPAM", "doppler", "amplitude", "detuning", "register"
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def _get_all_lindblad_noise_operators(
|
|
23
|
-
noise_model: NoiseModel | None,
|
|
23
|
+
noise_model: NoiseModel | None, dim: int = 2, interact_type: str = "ising"
|
|
24
24
|
) -> list[torch.Tensor]:
|
|
25
25
|
if noise_model is None:
|
|
26
26
|
return []
|
|
@@ -29,7 +29,12 @@ def _get_all_lindblad_noise_operators(
|
|
|
29
29
|
op
|
|
30
30
|
for noise_type in noise_model.noise_types
|
|
31
31
|
if noise_type not in _NON_LINDBLADIAN_NOISE
|
|
32
|
-
for op in get_lindblad_operators(
|
|
32
|
+
for op in get_lindblad_operators(
|
|
33
|
+
noise_type=noise_type,
|
|
34
|
+
noise_model=noise_model,
|
|
35
|
+
dim=dim,
|
|
36
|
+
interact_type=interact_type,
|
|
37
|
+
)
|
|
33
38
|
]
|
|
34
39
|
|
|
35
40
|
|
|
@@ -150,6 +155,7 @@ class PulserData:
|
|
|
150
155
|
)
|
|
151
156
|
|
|
152
157
|
int_type = self.hamiltonian.interaction_type
|
|
158
|
+
self.dim = self.hamiltonian.dim
|
|
153
159
|
if int_type == "ising": # for local and global
|
|
154
160
|
self.hamiltonian_type = HamiltonianType.Rydberg
|
|
155
161
|
elif int_type == "XY":
|
|
@@ -157,7 +163,9 @@ class PulserData:
|
|
|
157
163
|
else:
|
|
158
164
|
raise ValueError(f"Unsupported basis: {int_type}")
|
|
159
165
|
|
|
160
|
-
self.lindblad_ops = _get_all_lindblad_noise_operators(
|
|
166
|
+
self.lindblad_ops = _get_all_lindblad_noise_operators(
|
|
167
|
+
config.noise_model, dim=self.dim, interact_type=int_type
|
|
168
|
+
)
|
|
161
169
|
self.has_lindblad_noise: bool = self.lindblad_ops != []
|
|
162
170
|
|
|
163
171
|
if config.interaction_matrix is not None:
|
emu_base/utils.py
CHANGED
|
@@ -2,12 +2,33 @@ from collections import Counter
|
|
|
2
2
|
import random
|
|
3
3
|
import torch
|
|
4
4
|
import os
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
5
8
|
|
|
6
9
|
unix_like = os.name != "nt"
|
|
7
10
|
if unix_like:
|
|
8
11
|
from resource import RUSAGE_SELF, getrusage
|
|
9
12
|
|
|
10
13
|
|
|
14
|
+
def init_logging(log_level: int, log_file: Path | None) -> logging.Logger:
|
|
15
|
+
logger = logging.getLogger("emulators")
|
|
16
|
+
logger.propagate = False
|
|
17
|
+
|
|
18
|
+
handler: logging.Handler
|
|
19
|
+
if log_file is None:
|
|
20
|
+
handler = logging.StreamHandler(sys.stdout)
|
|
21
|
+
else:
|
|
22
|
+
handler = logging.FileHandler(log_file, mode="w")
|
|
23
|
+
|
|
24
|
+
handler.setLevel(log_level)
|
|
25
|
+
handler.setFormatter(logging.Formatter("%(message)s"))
|
|
26
|
+
for h in logger.handlers:
|
|
27
|
+
logger.removeHandler(h)
|
|
28
|
+
logger.addHandler(handler)
|
|
29
|
+
return logger
|
|
30
|
+
|
|
31
|
+
|
|
11
32
|
def deallocate_tensor(t: torch.Tensor) -> None:
|
|
12
33
|
"""
|
|
13
34
|
Free the memory used by a tensor. This is done regardless of the
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
emu_base/__init__.py,sha256=
|
|
1
|
+
emu_base/__init__.py,sha256=D7NkoAkHyN0qILkIdfrzfs5-C2yl381TySMHwEWj14c,759
|
|
2
2
|
emu_base/constants.py,sha256=41LYkKLUCz-oxPbd-j7nUDZuhIbUrnez6prT0uR0jcE,56
|
|
3
|
-
emu_base/jump_lindblad_operators.py,sha256=
|
|
4
|
-
emu_base/pulser_adapter.py,sha256=
|
|
5
|
-
emu_base/utils.py,sha256=
|
|
3
|
+
emu_base/jump_lindblad_operators.py,sha256=Wioao_EohYXBrIRZ1yd_qD9K4rPx9_B0NBKKKwiYr18,3033
|
|
4
|
+
emu_base/pulser_adapter.py,sha256=W5e1NLqqrXwCbGAkUdww7DneDaYX981II5chifB89ek,7219
|
|
5
|
+
emu_base/utils.py,sha256=kXfRFq31r_dfLbBC0SHiPpvf7Wll4behd2vqQJsTrVo,3553
|
|
6
6
|
emu_base/math/__init__.py,sha256=6BbIytYV5uC-e5jLMtIErkcUl_PvfSNnhmVFY9Il8uQ,97
|
|
7
7
|
emu_base/math/brents_root_finding.py,sha256=AVx6L1Il6rpPJWrLJ7cn6oNmJyZOPRgEaaZaubC9lsU,3711
|
|
8
8
|
emu_base/math/double_krylov.py,sha256=X16dyCbyzdP7fFK-hmKS03Q-DJtC6TZ8sJrGTJ6akIc,3708
|
|
9
9
|
emu_base/math/krylov_energy_min.py,sha256=iR4hmE0eXptbAg3opikd5d4Zv7dhnDrawH-n_4KG-cc,4009
|
|
10
10
|
emu_base/math/krylov_exp.py,sha256=mGFddVQ8mEbwypbZtnlRPFpi4Nf8JZT6OKLHloIwCDQ,3934
|
|
11
11
|
emu_base/math/matmul.py,sha256=lEAnV0b5z_f1xEA-9p-WXxA8bM3QbShiHdXQ3ZkZFcQ,877
|
|
12
|
-
emu_base-2.4.
|
|
13
|
-
emu_base-2.4.
|
|
14
|
-
emu_base-2.4.
|
|
12
|
+
emu_base-2.4.4.dist-info/METADATA,sha256=e_i4b_tVdN2PTfEs12pUYGZgICeNUbAIzKpNAFBlsfU,3604
|
|
13
|
+
emu_base-2.4.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
14
|
+
emu_base-2.4.4.dist-info/RECORD,,
|
|
File without changes
|