dense-evolution 8.1.78__tar.gz → 8.1.80__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.
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/PKG-INFO +5 -2
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/README.md +1 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/__init__.py +1 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/_engine_imports.py +21 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/disk_overflow.py +35 -19
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/guard.py +25 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/kernels.py +10 -87
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/mps.py +11 -3
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/compiler.py +103 -113
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/registry.py +19 -10
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/interop/qiskit_pennylane.py +8 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/healing.py +16 -9
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/magic_entropy.py +7 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/assembly.py +116 -45
- dense_evolution-8.1.80/dense_evolution/native_hf/differentiable.py +53 -0
- dense_evolution-8.1.80/dense_evolution/native_hf/scf.py +327 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus_channels.py +12 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/physics/__init__.py +3 -2
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/physics/entropy.py +27 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/physics/observables.py +1 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/physics/qec.py +13 -5
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/solvers/autodiff.py +1 -1
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution.egg-info/PKG-INFO +5 -2
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution.egg-info/SOURCES.txt +3 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution.egg-info/requires.txt +3 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/pyproject.toml +15 -3
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/__init__.py +30 -10
- dense_evolution-8.1.80/tools/dashboard/core/_gate_tables.py +30 -0
- dense_evolution-8.1.80/tools/dashboard/core/band_structure.py +71 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/circuit_builder_component.py +5 -5
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/circuit_diagram.py +22 -10
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/engine.py +35 -3
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/graphical_builder.py +9 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/hamiltonians.py +21 -12
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/mitigation.py +20 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/noise_tools.py +10 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/qasm_library.py +5 -8
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/qmmm.py +81 -33
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/state_visuals.py +51 -3
- dense_evolution-8.1.80/tools/dashboard/core/visuals.py +158 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/vqe.py +80 -8
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/wormhole.py +19 -33
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/server.py +6 -2
- dense_evolution-8.1.78/dense_evolution/native_hf/scf.py +0 -240
- dense_evolution-8.1.78/tools/dashboard/core/visuals.py +0 -59
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/autodiff.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/circuit_chunker.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/core.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/geometry.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/statevector.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/chunk.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/diagram.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/gates.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/parser.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/qft.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/random_circuit.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/topology.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/trotter.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/circuits/uccsd.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/cli.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/compiler.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/config.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/drawing.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/entropy.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/fermions.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/gates.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/harrison_tb.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/healing.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/interop/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/measurement.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/kl_divergence.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/magic_entropy_shadows.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/renyi.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/stabilizer_renyi_entropy.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mitigation/zne.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/mps.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/basis.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/boys.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/bridge.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/cartesian.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/coulomb.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/gaussians.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/kinetic.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/libcint_bridge.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/native_hf/overlap.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/coherent_attack.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/cosmic_ray.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/density_matrix_channels.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/differentiable.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/amplitude_damping.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/bitflip.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/combined.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/depolarizing.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/ideal.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/kraus/phaseflip.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/noise/oscillating.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/observables.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/parser.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/physics/fermions.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/physics/states.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/qec.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/qft.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/random_circuit.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/registry.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/simulator.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/solvers/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/solvers/harrison_tb.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/solvers/vhd_tb.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/states.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/topology.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/trotter.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/utils/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/utils/drawing.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/utils/measurement.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/vhd_tb.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution.egg-info/dependency_links.txt +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution.egg-info/entry_points.txt +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution.egg-info/top_level.txt +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/license.md +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/research/local_site/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/research/local_site/app/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/research/local_site/app/server.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/setup.cfg +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/system_limits.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/dashboard/core/vector_healing.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/ia_utils/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/ia_utils/adversarial_vector_attack.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/ia_utils/vector_healing.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/client.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/config.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/models.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/molecules.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/chemistry_tools.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/circuit_tools.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/mitigation_tools.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/noise_tools.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/system_tools.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/tools/wormhole_tools.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/utils/__init__.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/utils/cache.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/utils/images.py +0 -0
- {dense_evolution-8.1.78 → dense_evolution-8.1.80}/tools/mcp_server/utils/truncation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dense-evolution
|
|
3
|
-
Version: 8.1.
|
|
3
|
+
Version: 8.1.80
|
|
4
4
|
Summary: High-performance quantum simulation toolkit -- Statevector/MPS engines with JIT compilation, noise modeling, VQE, QEC, quantum chemistry, and agent-native tooling
|
|
5
5
|
Author-email: Salvatore Pennacchio <jtatopenn@libero.it>
|
|
6
6
|
License: Business Source License 1.1
|
|
@@ -38,6 +38,7 @@ Provides-Extra: dashboard
|
|
|
38
38
|
Requires-Dist: streamlit>=1.30.0; extra == "dashboard"
|
|
39
39
|
Requires-Dist: qiskit>=1.0.0; extra == "dashboard"
|
|
40
40
|
Requires-Dist: pylatexenc>=2.10; extra == "dashboard"
|
|
41
|
+
Requires-Dist: plotly>=5.0.0; extra == "dashboard"
|
|
41
42
|
Provides-Extra: qiskit
|
|
42
43
|
Requires-Dist: qiskit>=1.0.0; extra == "qiskit"
|
|
43
44
|
Provides-Extra: pennylane
|
|
@@ -64,6 +65,7 @@ Requires-Dist: cupy-cuda12x>=12.0.0; extra == "full"
|
|
|
64
65
|
Requires-Dist: streamlit>=1.30.0; extra == "full"
|
|
65
66
|
Requires-Dist: qiskit>=1.0.0; extra == "full"
|
|
66
67
|
Requires-Dist: pylatexenc>=2.10; extra == "full"
|
|
68
|
+
Requires-Dist: plotly>=5.0.0; extra == "full"
|
|
67
69
|
Requires-Dist: pennylane>=0.35.0; extra == "full"
|
|
68
70
|
Requires-Dist: basis_set_exchange>=0.9; extra == "full"
|
|
69
71
|
Requires-Dist: fastapi>=0.110.0; extra == "full"
|
|
@@ -82,6 +84,7 @@ Requires-Dist: mkdocs-include-markdown-plugin>=6.0.0; extra == "docs"
|
|
|
82
84
|
Requires-Dist: ruff>=0.4.0; extra == "docs"
|
|
83
85
|
Requires-Dist: pennylane>=0.35.0; extra == "docs"
|
|
84
86
|
Requires-Dist: basis_set_exchange>=0.9; extra == "docs"
|
|
87
|
+
Requires-Dist: plotly>=5.0.0; extra == "docs"
|
|
85
88
|
Dynamic: license-file
|
|
86
89
|
|
|
87
90
|
<p align="center">
|
|
@@ -335,7 +338,7 @@ If Dense-Evolution is useful in academic work, please cite it via the metadata i
|
|
|
335
338
|
Archived on [Zenodo](https://zenodo.org/):
|
|
336
339
|
|
|
337
340
|
- **Concept DOI** (always resolves to the latest version): [10.5281/zenodo.21855643](https://doi.org/10.5281/zenodo.21855643)
|
|
338
|
-
- **This release (v8.1.
|
|
341
|
+
- **This release (v8.1.78)**: [10.5281/zenodo.22706039](https://doi.org/10.5281/zenodo.22706039)
|
|
339
342
|
|
|
340
343
|
---
|
|
341
344
|
|
|
@@ -249,7 +249,7 @@ If Dense-Evolution is useful in academic work, please cite it via the metadata i
|
|
|
249
249
|
Archived on [Zenodo](https://zenodo.org/):
|
|
250
250
|
|
|
251
251
|
- **Concept DOI** (always resolves to the latest version): [10.5281/zenodo.21855643](https://doi.org/10.5281/zenodo.21855643)
|
|
252
|
-
- **This release (v8.1.
|
|
252
|
+
- **This release (v8.1.78)**: [10.5281/zenodo.22706039](https://doi.org/10.5281/zenodo.22706039)
|
|
253
253
|
|
|
254
254
|
---
|
|
255
255
|
|
|
@@ -57,7 +57,7 @@ from .physics.qec import (pauli_commutes, compute_syndrome, erasure_aware_decode
|
|
|
57
57
|
blind_minimum_weight_decode, decode_with_erasure_fallback,
|
|
58
58
|
counts_in_intervals_dimension, nearest_coset_decode)
|
|
59
59
|
|
|
60
|
-
__version__ = "8.1.
|
|
60
|
+
__version__ = "8.1.80"
|
|
61
61
|
|
|
62
62
|
__all__ = [
|
|
63
63
|
"__version__",
|
{dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/_engine_imports.py
RENAMED
|
@@ -10,11 +10,13 @@ import numpy as np
|
|
|
10
10
|
try:
|
|
11
11
|
from simulator import DenseSVSimulator
|
|
12
12
|
from compiler import QuantumTranspiler # pragma: no cover
|
|
13
|
+
from circuits.compiler import _gate_1q_matrix # pragma: no cover
|
|
13
14
|
from gates import GATE_IDS # pragma: no cover
|
|
14
15
|
except ModuleNotFoundError:
|
|
15
16
|
try:
|
|
16
17
|
from dense_evolution.simulator import DenseSVSimulator
|
|
17
18
|
from dense_evolution.compiler import QuantumTranspiler
|
|
19
|
+
from dense_evolution.circuits.compiler import _gate_1q_matrix
|
|
18
20
|
from dense_evolution.gates import GATE_IDS
|
|
19
21
|
except ModuleNotFoundError: # pragma: no cover
|
|
20
22
|
class DenseSVSimulator: # type: ignore[no-redef]
|
|
@@ -28,10 +30,28 @@ except ModuleNotFoundError:
|
|
|
28
30
|
def memory_mb(self) -> float:
|
|
29
31
|
return (self.dim * np.dtype(self.dtype).itemsize) / 1_000_000
|
|
30
32
|
|
|
33
|
+
def _unavailable(self, name):
|
|
34
|
+
raise NotImplementedError(
|
|
35
|
+
f"DenseSVSimulator stub: {name}() is not implemented here -- this "
|
|
36
|
+
"class only exists because the real dense_evolution/JAX modules "
|
|
37
|
+
"were not importable in this deployment (see this module's own "
|
|
38
|
+
"comment above); it is not a working simulator."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def get_probabilities(self): self._unavailable("get_probabilities")
|
|
42
|
+
def get_statevector(self): self._unavailable("get_statevector")
|
|
43
|
+
def apply_gate_1q(self, gate, q1): self._unavailable("apply_gate_1q")
|
|
44
|
+
def apply_gate_2q(self, gate, q1, q2): self._unavailable("apply_gate_2q")
|
|
45
|
+
|
|
31
46
|
class QuantumTranspiler: # type: ignore[no-redef]
|
|
32
47
|
@staticmethod
|
|
33
48
|
def transpile(circuit): return circuit
|
|
34
49
|
|
|
50
|
+
def _gate_1q_matrix(g_id, param, dtype): # type: ignore[no-redef]
|
|
51
|
+
raise NotImplementedError(
|
|
52
|
+
"_gate_1q_matrix stub: real dense_evolution/JAX not importable in this deployment"
|
|
53
|
+
)
|
|
54
|
+
|
|
35
55
|
GATE_IDS: dict = {}
|
|
36
56
|
|
|
37
|
-
__all__ = ["DenseSVSimulator", "QuantumTranspiler", "GATE_IDS"]
|
|
57
|
+
__all__ = ["DenseSVSimulator", "QuantumTranspiler", "GATE_IDS", "_gate_1q_matrix"]
|
{dense_evolution-8.1.78 → dense_evolution-8.1.80}/dense_evolution/backends/chunk/disk_overflow.py
RENAMED
|
@@ -48,13 +48,17 @@ class LocalPhase:
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
class ConditionalPhase:
|
|
51
|
-
"""A
|
|
52
|
-
(q2 >= m) -- applied to each chunk independently,
|
|
53
|
-
that chunk's own absolute index (see
|
|
54
|
-
|
|
51
|
+
"""A maximal run of consecutive 2-qubit gates with ctrl chunk-select
|
|
52
|
+
(q1 < m), tgt local (q2 >= m) -- applied to each chunk independently,
|
|
53
|
+
each op conditioned on that chunk's own absolute index (see
|
|
54
|
+
_case_2q_ctrl_chunk_tgt_local). Batched the same way LocalPhase is
|
|
55
|
+
(was: strictly one gate per phase object, so consecutive
|
|
56
|
+
ConditionalPhase-eligible gates did one full disk load/save cycle per
|
|
57
|
+
chunk PER GATE instead of once for the whole run -- prog.txt point 5b)."""
|
|
58
|
+
__slots__ = ("ops",)
|
|
55
59
|
|
|
56
|
-
def __init__(self,
|
|
57
|
-
self.
|
|
60
|
+
def __init__(self, ops):
|
|
61
|
+
self.ops = ops # list of (g_id, q1, q2, param) python tuples
|
|
58
62
|
|
|
59
63
|
|
|
60
64
|
class MixPhase:
|
|
@@ -78,30 +82,41 @@ def partition_ops_into_phases(compiled_ops, m: int):
|
|
|
78
82
|
rows = np.asarray(compiled_ops)
|
|
79
83
|
phases = []
|
|
80
84
|
pending_local = []
|
|
85
|
+
pending_conditional = []
|
|
81
86
|
|
|
82
|
-
def
|
|
87
|
+
def flush_local():
|
|
83
88
|
if pending_local:
|
|
84
89
|
phases.append(LocalPhase(list(pending_local)))
|
|
85
90
|
pending_local.clear()
|
|
86
91
|
|
|
92
|
+
def flush_conditional():
|
|
93
|
+
if pending_conditional:
|
|
94
|
+
phases.append(ConditionalPhase(list(pending_conditional)))
|
|
95
|
+
pending_conditional.clear()
|
|
96
|
+
|
|
87
97
|
for row in rows:
|
|
88
98
|
g_id, q1, q2, param = int(row[0]), int(row[1]), int(row[2]), float(row[3])
|
|
89
99
|
is_2q = g_id >= 20
|
|
90
100
|
if not is_2q:
|
|
91
101
|
if q1 < m:
|
|
92
|
-
|
|
102
|
+
flush_local()
|
|
103
|
+
flush_conditional()
|
|
93
104
|
phases.append(MixPhase((g_id, q1, q2, param), q1))
|
|
94
105
|
else:
|
|
106
|
+
flush_conditional()
|
|
95
107
|
pending_local.append((g_id, q1, q2, param))
|
|
96
108
|
elif q1 < m and q2 >= m:
|
|
97
|
-
|
|
98
|
-
|
|
109
|
+
flush_local()
|
|
110
|
+
pending_conditional.append((g_id, q1, q2, param))
|
|
99
111
|
elif q2 < m:
|
|
100
|
-
|
|
112
|
+
flush_local()
|
|
113
|
+
flush_conditional()
|
|
101
114
|
phases.append(MixPhase((g_id, q1, q2, param), q2))
|
|
102
115
|
else:
|
|
116
|
+
flush_conditional()
|
|
103
117
|
pending_local.append((g_id, q1, q2, param))
|
|
104
|
-
|
|
118
|
+
flush_local()
|
|
119
|
+
flush_conditional()
|
|
105
120
|
return phases
|
|
106
121
|
|
|
107
122
|
|
|
@@ -122,16 +137,17 @@ def _run_local_phase_on_chunk(chunk_arr, ops, m: int, k: int):
|
|
|
122
137
|
return c[0]
|
|
123
138
|
|
|
124
139
|
|
|
125
|
-
def _run_conditional_phase_on_chunk(chunk_arr,
|
|
126
|
-
"""A
|
|
140
|
+
def _run_conditional_phase_on_chunk(chunk_arr, ops, chunk_index: int, m: int, k: int):
|
|
141
|
+
"""A run of ConditionalPhase gates, applied to one chunk whose real
|
|
127
142
|
absolute index is `chunk_index` (needed for the ctrl-bit decision;
|
|
128
|
-
see _case_2q_ctrl_chunk_tgt_local's own docstring).
|
|
129
|
-
|
|
143
|
+
see _case_2q_ctrl_chunk_tgt_local's own docstring). Same load-once/
|
|
144
|
+
apply-all/save-once shape as _run_local_phase_on_chunk."""
|
|
130
145
|
dtype = chunk_arr.dtype
|
|
131
|
-
_, _, _, _, u00, u01, u10, u11 = _gate_matrix_elements(g_id, param, dtype)
|
|
132
146
|
c = chunk_arr[None, :]
|
|
133
147
|
idxc = jnp.array([chunk_index], dtype=jnp.int32)
|
|
134
|
-
|
|
148
|
+
for g_id, q1, q2, param in ops:
|
|
149
|
+
_, _, _, _, u00, u01, u10, u11 = _gate_matrix_elements(g_id, param, dtype)
|
|
150
|
+
c = _case_2q_ctrl_chunk_tgt_local(c, u00, u01, u10, u11, q1, q2, m, k, idxc)
|
|
135
151
|
return c[0]
|
|
136
152
|
|
|
137
153
|
|
|
@@ -197,7 +213,7 @@ def run_disk_overflow_circuit(chunk_paths, compiled_ops, m: int, k: int):
|
|
|
197
213
|
elif isinstance(phase, ConditionalPhase):
|
|
198
214
|
for i, path in enumerate(chunk_paths):
|
|
199
215
|
arr = jnp.asarray(np.load(path))
|
|
200
|
-
arr = _run_conditional_phase_on_chunk(arr, phase.
|
|
216
|
+
arr = _run_conditional_phase_on_chunk(arr, phase.ops, i, m, k)
|
|
201
217
|
np.save(path, np.asarray(arr))
|
|
202
218
|
|
|
203
219
|
elif isinstance(phase, MixPhase):
|
|
@@ -74,6 +74,27 @@ class SafeMemoryGuard:
|
|
|
74
74
|
"""
|
|
75
75
|
|
|
76
76
|
_WARN_MULTIPLIER = 2.0
|
|
77
|
+
# Below this, check_allocation's own margin-after-allocation math
|
|
78
|
+
# reduces to "is ambient free RAM currently below threshold_pct?",
|
|
79
|
+
# independent of required_mb -- for a request this small that's not
|
|
80
|
+
# protecting against anything, since real machines don't run out of
|
|
81
|
+
# memory over a request this size regardless of ambient load. Sized
|
|
82
|
+
# to comfortably cover a dense statevector up to 24 qubits at
|
|
83
|
+
# complex128 (2**24 * 16 bytes = 268.4 MB) with a real margin -- the
|
|
84
|
+
# same 24-qubit figure dashboard_core.system_limits already treats as
|
|
85
|
+
# MPS's own RAM-independent ceiling, and well inside the 16-27 qubit
|
|
86
|
+
# range dense_evolution.chunk.get_dynamic_chunk considers safe on any
|
|
87
|
+
# machine (27 qubits / 2 GB is that function's own practical ceiling
|
|
88
|
+
# for a single dense block). An 8 GB minimum-spec machine can always
|
|
89
|
+
# absorb an allocation this size without real risk, even while
|
|
90
|
+
# running low on RAM from unrelated processes. A 2-qubit statevector
|
|
91
|
+
# (64 bytes) used to be refused on a machine sitting at 8% free RAM
|
|
92
|
+
# from unrelated processes, which was not a real anti-OOM save, just
|
|
93
|
+
# a false positive from a threshold designed for actual multi-GB
|
|
94
|
+
# allocations. Only bypasses when available_mb is itself comfortably
|
|
95
|
+
# above this floor too (see check_allocation below) -- a machine
|
|
96
|
+
# truly down to its last few hundred MB still gets the real check.
|
|
97
|
+
_NEGLIGIBLE_MB = 512.0
|
|
77
98
|
|
|
78
99
|
def __init__(self, threshold_pct: float = 0.15, gc_before_check: bool = True):
|
|
79
100
|
if not 0.0 < threshold_pct < 1.0:
|
|
@@ -134,7 +155,10 @@ class SafeMemoryGuard:
|
|
|
134
155
|
if self.gc_before_check:
|
|
135
156
|
gc.collect()
|
|
136
157
|
|
|
137
|
-
s
|
|
158
|
+
s = self.status()
|
|
159
|
+
if required_mb < self._NEGLIGIBLE_MB and s["available_mb"] > self._NEGLIGIBLE_MB:
|
|
160
|
+
return
|
|
161
|
+
|
|
138
162
|
tag = f"[{context}] " if context else ""
|
|
139
163
|
available_after_mb = s["available_mb"] - required_mb
|
|
140
164
|
free_frac_after = available_after_mb / self._total_mb if self._total_mb > 0 else 0.0
|
|
@@ -4,7 +4,7 @@ from typing import List
|
|
|
4
4
|
import jax
|
|
5
5
|
import jax.numpy as jnp
|
|
6
6
|
|
|
7
|
-
from ._engine_imports import QuantumTranspiler, GATE_IDS
|
|
7
|
+
from ._engine_imports import QuantumTranspiler, GATE_IDS, _gate_1q_matrix
|
|
8
8
|
|
|
9
9
|
__all__ = [
|
|
10
10
|
"_build_multi_chunk_step", "_build_multi_chunk_runner",
|
|
@@ -44,45 +44,17 @@ def _gate_matrix_elements(g_id, param, dtype):
|
|
|
44
44
|
be traced (the in-RAM scan) or concrete Python/jnp scalars (a single
|
|
45
45
|
known gate in a phase); jax.lax.switch works identically either way.
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
The 1-qubit table itself lives in compiler.py's _gate_1q_matrix now
|
|
48
|
+
(was: an independent hand-copied switch here, with a "must stay in
|
|
49
|
+
sync" comment -- prog.txt point 2); only the 2-qubit controlled-U
|
|
50
|
+
table below is local to this module."""
|
|
51
51
|
half_p = param * jnp.float64(0.5)
|
|
52
|
-
cos_p = jnp.cos(half_p).astype(dtype)
|
|
53
|
-
sin_p = jnp.sin(half_p).astype(dtype)
|
|
54
52
|
exp_pos = jnp.exp(1j * param).astype(dtype)
|
|
55
|
-
exp_ph4 = jnp.exp(1j * jnp.pi / 4.0).astype(dtype)
|
|
56
|
-
exp_mh4 = jnp.exp(-1j * jnp.pi / 4.0).astype(dtype)
|
|
57
53
|
exp_pos_half = jnp.exp(1j * half_p).astype(dtype)
|
|
58
54
|
exp_neg_half = jnp.exp(-1j * half_p).astype(dtype)
|
|
59
55
|
|
|
60
56
|
g_id = jnp.asarray(g_id).astype(jnp.int32)
|
|
61
|
-
|
|
62
|
-
g_1q = jax.lax.switch(
|
|
63
|
-
safe_gid,
|
|
64
|
-
[
|
|
65
|
-
lambda _: jnp.eye(2, dtype=dtype),
|
|
66
|
-
lambda _: jnp.array([[inv2, inv2], [inv2, -inv2]], dtype=dtype),
|
|
67
|
-
lambda _: jnp.array([[0.0 + 0j, 1.0 + 0j], [1.0 + 0j, 0.0 + 0j]], dtype=dtype),
|
|
68
|
-
lambda _: jnp.array([[0.0 + 0j, -1j], [1j, 0.0 + 0j]], dtype=dtype),
|
|
69
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, -1.0 + 0j]], dtype=dtype),
|
|
70
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, 1j]], dtype=dtype),
|
|
71
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, -1j]], dtype=dtype),
|
|
72
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_ph4]], dtype=dtype),
|
|
73
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_mh4]], dtype=dtype),
|
|
74
|
-
lambda _: jnp.array([[cos_p, -1j * sin_p], [-1j * sin_p, cos_p]], dtype=dtype),
|
|
75
|
-
lambda _: jnp.array([[cos_p, -sin_p], [sin_p, cos_p]], dtype=dtype),
|
|
76
|
-
lambda _: jnp.array([[jnp.exp(-1j * half_p), 0.0 + 0j], [0.0 + 0j, jnp.exp(1j * half_p)]], dtype=dtype),
|
|
77
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_pos]], dtype=dtype),
|
|
78
|
-
lambda _: jnp.array([[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]], dtype=dtype),
|
|
79
|
-
# 14 GPhase(alpha) = e^{i*alpha} * I -- see compiler.py's
|
|
80
|
-
# _apply_gate_fast_step index 14 for the derivation; this
|
|
81
|
-
# table must stay in sync with that one (see comment above).
|
|
82
|
-
lambda _: jnp.array([[exp_pos, 0.0 + 0j], [0.0 + 0j, exp_pos]], dtype=dtype),
|
|
83
|
-
],
|
|
84
|
-
operand=None,
|
|
85
|
-
)
|
|
57
|
+
g_1q = _gate_1q_matrix(g_id, param, dtype)
|
|
86
58
|
|
|
87
59
|
# Controlled-U submatrix for the 5 two-qubit gate types (mat[2:,2:]
|
|
88
60
|
# of each gate's full 4x4 form — same values _apply_gate_multi's
|
|
@@ -319,59 +291,10 @@ def _build_distributed_chunk_step(num_chunks: int, m: int, k: int, axis_name: st
|
|
|
319
291
|
|
|
320
292
|
my_id = jax.lax.axis_index(axis_name).astype(jnp.int32)
|
|
321
293
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
exp_pos = jnp.exp(1j * param).astype(dtype)
|
|
327
|
-
exp_ph4 = jnp.exp(1j * jnp.pi / 4.0).astype(dtype)
|
|
328
|
-
exp_mh4 = jnp.exp(-1j * jnp.pi / 4.0).astype(dtype)
|
|
329
|
-
exp_pos_half = jnp.exp(1j * half_p).astype(dtype)
|
|
330
|
-
exp_neg_half = jnp.exp(-1j * half_p).astype(dtype)
|
|
331
|
-
|
|
332
|
-
safe_gid = jnp.clip(g_id, 0, 14)
|
|
333
|
-
g_1q = jax.lax.switch(
|
|
334
|
-
safe_gid,
|
|
335
|
-
[
|
|
336
|
-
lambda _: jnp.eye(2, dtype=dtype),
|
|
337
|
-
lambda _: jnp.array([[inv2, inv2], [inv2, -inv2]], dtype=dtype),
|
|
338
|
-
lambda _: jnp.array([[0.0 + 0j, 1.0 + 0j], [1.0 + 0j, 0.0 + 0j]], dtype=dtype),
|
|
339
|
-
lambda _: jnp.array([[0.0 + 0j, -1j], [1j, 0.0 + 0j]], dtype=dtype),
|
|
340
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, -1.0 + 0j]], dtype=dtype),
|
|
341
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, 1j]], dtype=dtype),
|
|
342
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, -1j]], dtype=dtype),
|
|
343
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_ph4]], dtype=dtype),
|
|
344
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_mh4]], dtype=dtype),
|
|
345
|
-
lambda _: jnp.array([[cos_p, -1j * sin_p], [-1j * sin_p, cos_p]], dtype=dtype),
|
|
346
|
-
lambda _: jnp.array([[cos_p, -sin_p], [sin_p, cos_p]], dtype=dtype),
|
|
347
|
-
lambda _: jnp.array([[jnp.exp(-1j * half_p), 0.0 + 0j], [0.0 + 0j, jnp.exp(1j * half_p)]], dtype=dtype),
|
|
348
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_pos]], dtype=dtype),
|
|
349
|
-
lambda _: jnp.array([[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]], dtype=dtype),
|
|
350
|
-
# 14 GPhase(alpha) = e^{i*alpha} * I -- must stay in sync
|
|
351
|
-
# with _apply_gate_fast_step (compiler.py) and the
|
|
352
|
-
# non-distributed copy of this table above.
|
|
353
|
-
lambda _: jnp.array([[exp_pos, 0.0 + 0j], [0.0 + 0j, exp_pos]], dtype=dtype),
|
|
354
|
-
],
|
|
355
|
-
operand=None,
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
two_q_idx = jnp.where(g_id == 20, 0,
|
|
359
|
-
jnp.where(g_id == 21, 1,
|
|
360
|
-
jnp.where(g_id == 22, 2,
|
|
361
|
-
jnp.where(g_id == 24, 3, 4))))
|
|
362
|
-
U = jax.lax.switch(
|
|
363
|
-
two_q_idx,
|
|
364
|
-
[
|
|
365
|
-
lambda _: jnp.array([[0.0 + 0j, 1.0 + 0j], [1.0 + 0j, 0.0 + 0j]], dtype=dtype),
|
|
366
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, -1.0 + 0j]], dtype=dtype),
|
|
367
|
-
lambda _: jnp.array([[1.0 + 0j, 0.0 + 0j], [0.0 + 0j, exp_pos]], dtype=dtype),
|
|
368
|
-
lambda _: jnp.array([[0.0 + 0j, -1j], [1j, 0.0 + 0j]], dtype=dtype),
|
|
369
|
-
lambda _: jnp.array([[exp_neg_half, 0.0 + 0j], [0.0 + 0j, exp_pos_half]], dtype=dtype),
|
|
370
|
-
],
|
|
371
|
-
operand=None,
|
|
372
|
-
)
|
|
373
|
-
g00, g01, g10, g11 = g_1q[0, 0], g_1q[0, 1], g_1q[1, 0], g_1q[1, 1]
|
|
374
|
-
u00, u01, u10, u11 = U[0, 0], U[0, 1], U[1, 0], U[1, 1]
|
|
294
|
+
# Same table _build_multi_chunk_step uses (was: an independent
|
|
295
|
+
# hand-copied switch here -- prog.txt point 2, "must stay in
|
|
296
|
+
# sync" comment on both sides).
|
|
297
|
+
g00, g01, g10, g11, u00, u01, u10, u11 = _gate_matrix_elements(g_id, param, dtype)
|
|
375
298
|
|
|
376
299
|
is_2q = g_id >= 20
|
|
377
300
|
q1_chunk = q1 < m
|
|
@@ -51,6 +51,7 @@ complementary.
|
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
53
|
import dataclasses
|
|
54
|
+
import heapq
|
|
54
55
|
import warnings
|
|
55
56
|
from functools import partial
|
|
56
57
|
from typing import List, Optional, Tuple
|
|
@@ -1161,7 +1162,7 @@ class MPSSimulator:
|
|
|
1161
1162
|
# candidate as a whole regardless of backend.
|
|
1162
1163
|
def _sample_bitstring(self, rng: np.random.Generator) -> List[int]:
|
|
1163
1164
|
bits = []
|
|
1164
|
-
state = jnp.ones(1, dtype=
|
|
1165
|
+
state = jnp.ones(1, dtype=self.gammas[0].dtype)
|
|
1165
1166
|
for i in range(self.n):
|
|
1166
1167
|
g = self.gammas[i]
|
|
1167
1168
|
lam = self.lambdas[i + 1] if i < self.n - 1 else jnp.ones(g.shape[2])
|
|
@@ -1214,8 +1215,15 @@ class MPSSimulator:
|
|
|
1214
1215
|
new_vec = jnp.einsum("l,lr->r", vec_p, gamma[:, bit, :]) * lam
|
|
1215
1216
|
weight = float(jnp.sum(jnp.abs(new_vec) ** 2))
|
|
1216
1217
|
candidates.append(((idx_p << 1) | bit, new_vec, weight))
|
|
1217
|
-
|
|
1218
|
-
|
|
1218
|
+
# heapq.nlargest instead of a full sort-then-slice (prog.txt
|
|
1219
|
+
# point 5e): only the top k by weight are ever used below, and
|
|
1220
|
+
# this avoids materializing/sorting the full candidates list
|
|
1221
|
+
# when len(candidates) >> k. Final probability order is
|
|
1222
|
+
# re-derived from scratch at the end of this function anyway
|
|
1223
|
+
# (`order = np.argsort(-probabilities)`), so which of two
|
|
1224
|
+
# equal-weight candidates heapq happens to prefer over sort's
|
|
1225
|
+
# stable order has no effect on the result.
|
|
1226
|
+
paths = [(idx, vec) for idx, vec, _ in heapq.nlargest(k, candidates, key=lambda c: c[2])]
|
|
1219
1227
|
|
|
1220
1228
|
indices = np.array([p[0] for p in paths])
|
|
1221
1229
|
amplitudes = np.array([
|