emu-mps 2.4.3__py3-none-any.whl → 2.5.0__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_mps/__init__.py CHANGED
@@ -36,4 +36,4 @@ __all__ = [
36
36
  "EntanglementEntropy",
37
37
  ]
38
38
 
39
- __version__ = "2.4.3"
39
+ __version__ = "2.5.0"
emu_mps/mps.py CHANGED
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
  import math
3
3
  from collections import Counter
4
4
  from typing import List, Optional, Sequence, TypeVar, Mapping
5
-
5
+ import logging
6
6
  import torch
7
7
 
8
8
  from pulser.backend.state import State, Eigenstate
@@ -481,7 +481,9 @@ class MPS(State[complex, torch.Tensor]):
481
481
  accum_mps += amplitude * MPS(factors, eigenstates=eigenstates)
482
482
  norm = accum_mps.norm()
483
483
  if not math.isclose(1.0, norm, rel_tol=1e-5, abs_tol=0.0):
484
- print("\nThe state is not normalized, normalizing it for you.")
484
+ logging.getLogger("emulators").warning(
485
+ "\nThe state is not normalized, normalizing it for you."
486
+ )
485
487
  accum_mps *= 1 / norm
486
488
 
487
489
  return accum_mps, amplitudes
emu_mps/mps_backend.py CHANGED
@@ -1,10 +1,10 @@
1
1
  from pulser.backend import EmulatorBackend, Results
2
2
  from emu_mps.mps_config import MPSConfig
3
+ from emu_base import init_logging
3
4
  from emu_mps.mps_backend_impl import create_impl, MPSBackendImpl
4
5
  import pickle
5
6
  import os
6
7
  import time
7
- import logging
8
8
  import pathlib
9
9
 
10
10
 
@@ -34,9 +34,9 @@ class MPSBackend(EmulatorBackend):
34
34
 
35
35
  impl.autosave_file = autosave_file
36
36
  impl.last_save_time = time.time()
37
- impl.config.init_logging() # FIXME: might be best to take logger object out of config.
37
+ init_logging(impl.config.log_level, impl.config.log_file)
38
38
 
39
- logging.getLogger("global_logger").warning(
39
+ impl.config.logger.warning(
40
40
  f"Resuming simulation from file {autosave_file}\n"
41
41
  f"Saving simulation state every {impl.config.autosave_dt} seconds"
42
42
  )
@@ -119,6 +119,7 @@ class MPSBackendImpl:
119
119
  self.phi = pulser_data.phi
120
120
  self.timestep_count: int = self.omega.shape[0]
121
121
  self.has_lindblad_noise = pulser_data.has_lindblad_noise
122
+ self.eigenstates = pulser_data.eigenstates
122
123
  self.dim = pulser_data.dim
123
124
  self.lindblad_noise = torch.zeros(self.dim, self.dim, dtype=dtype)
124
125
  self.qubit_permutation = (
@@ -220,6 +221,7 @@ class MPSBackendImpl:
220
221
  precision=self.config.precision,
221
222
  max_bond_dim=self.config.max_bond_dim,
222
223
  num_gpus_to_use=self.resolved_num_gpus,
224
+ eigenstates=self.eigenstates,
223
225
  )
224
226
  return
225
227
 
@@ -268,6 +270,7 @@ class MPSBackendImpl:
268
270
  ),
269
271
  hamiltonian_type=self.hamiltonian_type,
270
272
  num_gpus_to_use=self.resolved_num_gpus,
273
+ dim=self.dim,
271
274
  )
272
275
 
273
276
  update_H(
@@ -342,6 +345,7 @@ class MPSBackendImpl:
342
345
  config=self.config,
343
346
  orth_center_right=orth_center_right,
344
347
  is_hermitian=not self.has_lindblad_noise,
348
+ dim=self.dim,
345
349
  )
346
350
 
347
351
  self.state.orthogonality_center = r if orth_center_right else l
@@ -616,7 +620,7 @@ class NoisyMPSBackendImpl(MPSBackendImpl):
616
620
  # The below is used for batch computation of noise collapse weights.
617
621
  self.aggregated_lindblad_ops = stacked.conj().transpose(1, 2) @ stacked
618
622
 
619
- self.lindblad_noise = compute_noise_from_lindbladians(self.lindblad_ops)
623
+ self.lindblad_noise = compute_noise_from_lindbladians(self.lindblad_ops, self.dim)
620
624
 
621
625
  def set_jump_threshold(self, bound: float) -> None:
622
626
  self.jump_threshold = random.uniform(0.0, bound)
emu_mps/mps_config.py CHANGED
@@ -3,6 +3,7 @@ from types import MethodType
3
3
 
4
4
  import copy
5
5
 
6
+ from emu_base import init_logging
6
7
  from emu_mps.mps import MPS, DEFAULT_MAX_BOND_DIM, DEFAULT_PRECISION
7
8
  from emu_mps.mpo import MPO
8
9
  from emu_mps.solver import Solver
@@ -24,7 +25,6 @@ from pulser.backend import (
24
25
  )
25
26
  import logging
26
27
  import pathlib
27
- import sys
28
28
 
29
29
 
30
30
  class MPSConfig(EmulationConfig):
@@ -90,7 +90,7 @@ class MPSConfig(EmulationConfig):
90
90
  max_krylov_dim: int = 100,
91
91
  extra_krylov_tolerance: float = 1e-3,
92
92
  num_gpus_to_use: int | None = None,
93
- optimize_qubit_ordering: bool = False,
93
+ optimize_qubit_ordering: bool = True,
94
94
  interaction_cutoff: float = 0.0,
95
95
  log_level: int = logging.INFO,
96
96
  log_file: pathlib.Path | None = None,
@@ -116,8 +116,6 @@ class MPSConfig(EmulationConfig):
116
116
  solver=solver,
117
117
  **kwargs,
118
118
  )
119
- if self.optimize_qubit_ordering:
120
- self.check_permutable_observables()
121
119
 
122
120
  MIN_AUTOSAVE_DT = 10
123
121
  assert (
@@ -125,20 +123,8 @@ class MPSConfig(EmulationConfig):
125
123
  ), f"autosave_dt must be larger than {MIN_AUTOSAVE_DT} seconds"
126
124
 
127
125
  self.monkeypatch_observables()
126
+ self.logger = init_logging(log_level, log_file)
128
127
 
129
- self.logger = logging.getLogger("global_logger")
130
- if log_file is None:
131
- logging.basicConfig(
132
- level=log_level, format="%(message)s", stream=sys.stdout, force=True
133
- ) # default to stream = sys.stderr
134
- else:
135
- logging.basicConfig(
136
- level=log_level,
137
- format="%(message)s",
138
- filename=str(log_file),
139
- filemode="w",
140
- force=True,
141
- )
142
128
  if (self.noise_model.runs != 1 and self.noise_model.runs is not None) or (
143
129
  self.noise_model.samples_per_run != 1
144
130
  and self.noise_model.samples_per_run is not None
@@ -146,6 +132,9 @@ class MPSConfig(EmulationConfig):
146
132
  self.logger.warning(
147
133
  "Warning: The runs and samples_per_run values of the NoiseModel are ignored!"
148
134
  )
135
+ self._backend_options[
136
+ "optimize_qubit_ordering"
137
+ ] &= self.check_permutable_observables()
149
138
 
150
139
  def _expected_kwargs(self) -> set[str]:
151
140
  return super()._expected_kwargs() | {
@@ -191,21 +180,7 @@ class MPSConfig(EmulationConfig):
191
180
  obs_list.append(obs_copy)
192
181
  self.observables = tuple(obs_list)
193
182
 
194
- def init_logging(self) -> None:
195
- if self.log_file is None:
196
- logging.basicConfig(
197
- level=self.log_level, format="%(message)s", stream=sys.stdout, force=True
198
- ) # default to stream = sys.stderr
199
- else:
200
- logging.basicConfig(
201
- level=self.log_level,
202
- format="%(message)s",
203
- filename=str(self.log_file),
204
- filemode="w",
205
- force=True,
206
- )
207
-
208
- def check_permutable_observables(self) -> None:
183
+ def check_permutable_observables(self) -> bool:
209
184
  allowed_permutable_obs = set(
210
185
  [
211
186
  "bitstrings",
@@ -221,10 +196,10 @@ class MPSConfig(EmulationConfig):
221
196
  actual_obs = set([obs._base_tag for obs in self.observables])
222
197
  not_allowed = actual_obs.difference(allowed_permutable_obs)
223
198
  if not_allowed:
224
- raise ValueError(
199
+ self.logger.warning(
225
200
  f"emu-mps allows only {allowed_permutable_obs} observables with"
226
201
  " `optimize_qubit_ordering = True`."
227
202
  f" you provided unsupported {not_allowed}"
228
- " To use other observables, please set"
229
- " `optimize_qubit_ordering = False` in `MPSConfig()`."
203
+ " using `optimize_qubit_ordering = False` instead."
230
204
  )
205
+ return not_allowed == set()
emu_mps/solver_utils.py CHANGED
@@ -14,6 +14,7 @@ def make_op(
14
14
  state_factors: Sequence[torch.Tensor],
15
15
  baths: tuple[torch.Tensor, torch.Tensor],
16
16
  ham_factors: Sequence[torch.Tensor],
17
+ dim: int = 2,
17
18
  ) -> tuple[torch.Tensor, torch.device, Callable[[torch.Tensor], torch.Tensor]]:
18
19
  assert len(state_factors) == 2
19
20
  assert len(baths) == 2
@@ -35,7 +36,7 @@ def make_op(
35
36
 
36
37
  combined_state_factors = torch.tensordot(
37
38
  left_state_factor, right_state_factor, dims=1
38
- ).reshape(left_bond_dim, 4, right_bond_dim)
39
+ ).reshape(left_bond_dim, dim**2, right_bond_dim)
39
40
 
40
41
  deallocate_tensor(left_state_factor)
41
42
  deallocate_tensor(right_state_factor)
@@ -48,7 +49,7 @@ def make_op(
48
49
  torch.tensordot(left_ham_factor, right_ham_factor, dims=1)
49
50
  .transpose(2, 3)
50
51
  .contiguous()
51
- .view(left_ham_factor.shape[0], 4, 4, -1)
52
+ .view(left_ham_factor.shape[0], dim**2, dim**2, -1)
52
53
  )
53
54
 
54
55
  def op(x: torch.Tensor) -> torch.Tensor:
@@ -151,6 +152,7 @@ def evolve_pair(
151
152
  orth_center_right: bool,
152
153
  is_hermitian: bool,
153
154
  config: MPSConfig,
155
+ dim: int = 2,
154
156
  ) -> tuple[torch.Tensor, torch.Tensor]:
155
157
  """
156
158
  Time evolution of a pair of tensors of a tensor train using baths and truncated SVD.
@@ -165,6 +167,7 @@ def evolve_pair(
165
167
  state_factors=state_factors,
166
168
  baths=baths,
167
169
  ham_factors=ham_factors,
170
+ dim=dim,
168
171
  )
169
172
  left_bond_dim = combined_state_factors.shape[0]
170
173
  right_bond_dim = combined_state_factors.shape[-1]
@@ -176,7 +179,7 @@ def evolve_pair(
176
179
  norm_tolerance=config.precision * config.extra_krylov_tolerance,
177
180
  max_krylov_dim=config.max_krylov_dim,
178
181
  is_hermitian=is_hermitian,
179
- ).view(left_bond_dim * 2, 2 * right_bond_dim)
182
+ ).view(left_bond_dim * dim, dim * right_bond_dim)
180
183
 
181
184
  l, r = split_matrix(
182
185
  evol,
@@ -186,7 +189,9 @@ def evolve_pair(
186
189
  preserve_norm=not is_hermitian, # only relevant for computing jump times
187
190
  )
188
191
 
189
- return l.view(left_bond_dim, 2, -1), r.view(-1, 2, right_bond_dim).to(right_device)
192
+ return l.view(left_bond_dim, dim, -1), r.view(-1, dim, right_bond_dim).to(
193
+ right_device
194
+ )
190
195
 
191
196
 
192
197
  def evolve_single(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: emu-mps
3
- Version: 2.4.3
3
+ Version: 2.5.0
4
4
  Summary: Pasqal MPS based pulse emulator built on PyTorch
5
5
  Project-URL: Documentation, https://pasqal-io.github.io/emulators/
6
6
  Project-URL: Repository, https://github.com/pasqal-io/emulators
@@ -25,7 +25,7 @@ Classifier: Programming Language :: Python :: 3.10
25
25
  Classifier: Programming Language :: Python :: Implementation :: CPython
26
26
  Classifier: Programming Language :: Python :: Implementation :: PyPy
27
27
  Requires-Python: >=3.10
28
- Requires-Dist: emu-base==2.4.3
28
+ Requires-Dist: emu-base==2.5.0
29
29
  Description-Content-Type: text/markdown
30
30
 
31
31
  <div align="center">
@@ -1,19 +1,19 @@
1
- emu_mps/__init__.py,sha256=avViacgzWmSfTtWIUvoxlaE_1p7LRXPb9Hh5sWv8ND4,708
1
+ emu_mps/__init__.py,sha256=att-gSzRc9t4OvllrmSVf_vPjP2WlmqT_sBJ020sv0c,708
2
2
  emu_mps/algebra.py,sha256=VZ5uaX5PYWGqDCpRKKr819BLMMtT0pKDxc2HrlLCdgU,5423
3
3
  emu_mps/custom_callback_implementations.py,sha256=WeczmO6qkvBIipvXLqX45i3D7M4ovOrepusIGs6d2Ts,2420
4
4
  emu_mps/hamiltonian.py,sha256=OM0bPNZV7J5Egk6aTUwt4GaWqiUOP68ujZBTuqlBY1k,16289
5
5
  emu_mps/mpo.py,sha256=WmGDGkCMhlODmydd0b09YcSRlsk6Bg5xYQ4rXSNJvnY,9703
6
- emu_mps/mps.py,sha256=1aMvY4NQSBeAwzTwHRegXncGQqm-1g05W00OimFNzt8,21630
7
- emu_mps/mps_backend.py,sha256=bS83qFxvdoK-c12_1WaPw6O7xUc7vdWifZNHUzNP5sM,2091
8
- emu_mps/mps_backend_impl.py,sha256=LMvi7KpfnsNmbiwQHuCtoA2lsK3Pf1vETuipL7BlG5U,30688
9
- emu_mps/mps_config.py,sha256=j7rho3edFzDxPO_VX7j5jc0Drw9wO2NWRymkqZ9hzmU,9128
6
+ emu_mps/mps.py,sha256=9LcneNCGMLYQJfiTQrDzBKz-YQmcL76P9l-A-3_bXOI,21707
7
+ emu_mps/mps_backend.py,sha256=dXcW5Fa2AAL_WlHUgr30WS2l3qiDJgBVebiVpyYWpPM,2064
8
+ emu_mps/mps_backend_impl.py,sha256=WyB1PpC61rzrnr_c3epVZOhDtXLOdhQLsMgUtZQWCYg,30851
9
+ emu_mps/mps_config.py,sha256=btlygf6VDFna9TQus-zOmUqB6pfe_aoQmNoivfvxABk,8251
10
10
  emu_mps/observables.py,sha256=4C_ewkd3YkJP0xghTrGUTgXUGvJRCQcetb8cU0SjMl0,1900
11
11
  emu_mps/solver.py,sha256=M9xkHhlEouTBvoPw2UYVu6kij7CO4Z1FXw_SiGFtdgo,85
12
- emu_mps/solver_utils.py,sha256=CklWjVvhngpyElpJyfUTncr4ErBP6VbUE3Z9nf8s3mM,8762
12
+ emu_mps/solver_utils.py,sha256=Q1SY8E3Kipe_RfKE8lAMRfD4mSG2VkkkPmk-fU7eAgY,8852
13
13
  emu_mps/utils.py,sha256=rL75H55hB5lDMjy8a_O2PpJq51iZKjSx91X4euxB3mY,7293
14
14
  emu_mps/optimatrix/__init__.py,sha256=fBXQ7-rgDro4hcaBijCGhx3J69W96qcw5_3mWc7tND4,364
15
15
  emu_mps/optimatrix/optimiser.py,sha256=k9suYmKLKlaZ7ozFuIqvXHyCBoCtGgkX1mpen9GOdOo,6977
16
16
  emu_mps/optimatrix/permutations.py,sha256=9DDMZtrGGZ01b9F3GkzHR3paX4qNtZiPoI7Z_Kia3Lc,3727
17
- emu_mps-2.4.3.dist-info/METADATA,sha256=hq605tOeTSfyZa9cNwSkVUH72t5ZTHfLo19Kll9-sxU,3587
18
- emu_mps-2.4.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
19
- emu_mps-2.4.3.dist-info/RECORD,,
17
+ emu_mps-2.5.0.dist-info/METADATA,sha256=La-IngskVDu8pMUaqmyqS_4Fe1qPAnOKfErnPsVpAiQ,3587
18
+ emu_mps-2.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
19
+ emu_mps-2.5.0.dist-info/RECORD,,