pygfmc 0.1.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.
- pygfmc/__init__.py +103 -0
- pygfmc/_output.py +20 -0
- pygfmc/_precision.py +9 -0
- pygfmc/_validation.py +19 -0
- pygfmc/engine/__init__.py +17 -0
- pygfmc/engine/driver.py +1510 -0
- pygfmc/engine/estimators.py +1362 -0
- pygfmc/engine/evolution.py +1101 -0
- pygfmc/engine/io.py +1540 -0
- pygfmc/engine/multi_gpu.py +866 -0
- pygfmc/hamiltonian/SpinHalf.py +649 -0
- pygfmc/hamiltonian/__init__.py +20 -0
- pygfmc/hamiltonian/_common.py +85 -0
- pygfmc/hamiltonian/bose_hubbard.py +479 -0
- pygfmc/hamiltonian/exact.py +375 -0
- pygfmc/hamiltonian/lattice.py +262 -0
- pygfmc/hamiltonian/observables.py +174 -0
- pygfmc/hamiltonian/plaquette.py +282 -0
- pygfmc/hamiltonian/spin.py +438 -0
- pygfmc/hamiltonian/toric.py +304 -0
- pygfmc/protocols.py +143 -0
- pygfmc/walkers/__init__.py +14 -0
- pygfmc/walkers/_h5io.py +27 -0
- pygfmc/walkers/reconfiguration.py +62 -0
- pygfmc/walkers/walker.py +342 -0
- pygfmc/wavefunction/__init__.py +20 -0
- pygfmc/wavefunction/_layout.py +19 -0
- pygfmc/wavefunction/_optional.py +35 -0
- pygfmc/wavefunction/_seed.py +19 -0
- pygfmc/wavefunction/_tied_params.py +66 -0
- pygfmc/wavefunction/cluster_cps.py +702 -0
- pygfmc/wavefunction/cluster_mlp.py +512 -0
- pygfmc/wavefunction/exact_ground_state.py +289 -0
- pygfmc/wavefunction/generic_netket_training.py +473 -0
- pygfmc/wavefunction/jastrow_bose_hubbard.py +341 -0
- pygfmc/wavefunction/jastrow_spin.py +318 -0
- pygfmc/wavefunction/jastrow_spin_half.py +499 -0
- pygfmc-0.1.0.dist-info/METADATA +317 -0
- pygfmc-0.1.0.dist-info/RECORD +43 -0
- pygfmc-0.1.0.dist-info/WHEEL +5 -0
- pygfmc-0.1.0.dist-info/licenses/LICENSE +202 -0
- pygfmc-0.1.0.dist-info/licenses/NOTICE +4 -0
- pygfmc-0.1.0.dist-info/top_level.txt +1 -0
pygfmc/__init__.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""PyGFMC — Green's Function Monte Carlo in JAX.
|
|
2
|
+
|
|
3
|
+
Subpackages: :mod:`pygfmc.walkers` (walker population, initializers,
|
|
4
|
+
reconfiguration), :mod:`pygfmc.engine` (propagation, estimators, I/O),
|
|
5
|
+
:mod:`pygfmc.hamiltonian` (models and lattices) and :mod:`pygfmc.wavefunction`
|
|
6
|
+
(guiding wavefunctions). The everyday engine API is re-exported here; the
|
|
7
|
+
walker functions are imported from :mod:`pygfmc.walkers`.
|
|
8
|
+
"""
|
|
9
|
+
import os as _os
|
|
10
|
+
|
|
11
|
+
# --------------------------------------------------------------------------
|
|
12
|
+
# Deterministic GPU kernels, ON BY DEFAULT.
|
|
13
|
+
#
|
|
14
|
+
# Without these flags a byte-identical invocation can produce a DIFFERENT
|
|
15
|
+
# Markov chain on GPU. The cause is not the RNG (JAX's counter-based PRNG has
|
|
16
|
+
# no hidden state and PRNGKey(seed) gives identical bits on any device) but
|
|
17
|
+
# floating-point summation order: XLA may combine partial sums in
|
|
18
|
+
# thread-completion order, float addition is not associative, and a 1-ULP
|
|
19
|
+
# shift in a weight normalisation can move a systematic-resampling boundary or
|
|
20
|
+
# a searchsorted threshold. One flipped discrete decision is then amplified by
|
|
21
|
+
# the chain.
|
|
22
|
+
#
|
|
23
|
+
# This does NOT change the physics: any trajectory produced by the correct
|
|
24
|
+
# kernel is a valid sample, equivalent to a different seed, and the ~1e-7
|
|
25
|
+
# relative FP noise sits orders of magnitude below the statistical error.
|
|
26
|
+
# What the flags buy is REPRODUCIBILITY (bit-identical reruns and resumes).
|
|
27
|
+
# Their throughput cost has not been measured carefully; it is expected to be
|
|
28
|
+
# small, since the hot path is gathers/scatters rather than GEMMs. Set
|
|
29
|
+
# PYGFMC_NONDETERMINISTIC=1 to disable them.
|
|
30
|
+
#
|
|
31
|
+
# NOT set here: JAX_DEFAULT_MATMUL_PRECISION=highest. TF32 is deterministic
|
|
32
|
+
# run-to-run on fixed hardware (it affects cross-hardware agreement, not the
|
|
33
|
+
# problem above) and forcing highest costs time on matmul-heavy guides such as
|
|
34
|
+
# ClusterMLP. Set it yourself if you need bitwise agreement across GPU models.
|
|
35
|
+
#
|
|
36
|
+
# XLA_FLAGS is read lazily at backend initialisation, not at `import jax`, so
|
|
37
|
+
# this works even if jax was imported earlier -- provided no JAX computation
|
|
38
|
+
# has run yet.
|
|
39
|
+
# --------------------------------------------------------------------------
|
|
40
|
+
def _enable_deterministic_xla():
|
|
41
|
+
if _os.environ.get("PYGFMC_NONDETERMINISTIC", "") not in ("", "0"):
|
|
42
|
+
return
|
|
43
|
+
existing = _os.environ.get("XLA_FLAGS", "")
|
|
44
|
+
# append only what the caller has not already specified, so an explicit
|
|
45
|
+
# user setting always wins
|
|
46
|
+
for flag in ("--xla_gpu_deterministic_ops=true",
|
|
47
|
+
"--xla_gpu_autotune_level=0"):
|
|
48
|
+
name = flag.split("=")[0]
|
|
49
|
+
if name not in existing:
|
|
50
|
+
existing = (existing + " " + flag).strip()
|
|
51
|
+
_os.environ["XLA_FLAGS"] = existing
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
_enable_deterministic_xla()
|
|
55
|
+
|
|
56
|
+
# PyGFMC runs in float32. ``import netket`` switches on jax_enable_x64
|
|
57
|
+
# process-wide unless NETKET_ENABLE_X64=0, and float64 walkers then meet a
|
|
58
|
+
# float32 Hamiltonian in the GFMC scan. NetKet's experimental sharding leaks a
|
|
59
|
+
# named mesh into JAX's config that breaks later ``jax.pmap`` calls. Importing
|
|
60
|
+
# pygfmc BEFORE netket avoids both; explicit settings by the user win.
|
|
61
|
+
# Newer NetKet releases read NETKET_SHARDING (the experimental name is
|
|
62
|
+
# deprecated), so both are set.
|
|
63
|
+
_os.environ.setdefault("NETKET_ENABLE_X64", "0")
|
|
64
|
+
_os.environ.setdefault("NETKET_EXPERIMENTAL_SHARDING", "0")
|
|
65
|
+
_os.environ.setdefault("NETKET_SHARDING", "0")
|
|
66
|
+
|
|
67
|
+
def _read_version():
|
|
68
|
+
"""The installed distribution's version, else the one in the source
|
|
69
|
+
tree's ``pyproject.toml`` (the single place the number is written)."""
|
|
70
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
71
|
+
try:
|
|
72
|
+
return version("pygfmc")
|
|
73
|
+
except PackageNotFoundError: # running from a source tree
|
|
74
|
+
pass
|
|
75
|
+
import re
|
|
76
|
+
pyproject = _os.path.join(_os.path.dirname(_os.path.dirname(
|
|
77
|
+
_os.path.abspath(__file__))), "pyproject.toml")
|
|
78
|
+
try:
|
|
79
|
+
with open(pyproject, encoding="utf-8") as f:
|
|
80
|
+
match = re.search(r'^version\s*=\s*"([^"]+)"', f.read(), re.M)
|
|
81
|
+
if match:
|
|
82
|
+
return match.group(1)
|
|
83
|
+
except OSError:
|
|
84
|
+
pass
|
|
85
|
+
return "0+unknown"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
__version__ = _read_version()
|
|
89
|
+
|
|
90
|
+
# The subpackages are imported only AFTER the XLA flags are set.
|
|
91
|
+
from . import walkers, engine, hamiltonian, wavefunction
|
|
92
|
+
from .protocols import Operator, DiagonalOperator, Guide
|
|
93
|
+
from .engine import (statistics, run_gfmc, run, write_to_HDF5, run_from_HDF5,
|
|
94
|
+
evaluate_observables, load_raw_from_HDF5,
|
|
95
|
+
check_run_compatible, resume_from_HDF5)
|
|
96
|
+
|
|
97
|
+
__all__ = [
|
|
98
|
+
"walkers", "engine", "hamiltonian", "wavefunction", "__version__",
|
|
99
|
+
"Operator", "DiagonalOperator", "Guide",
|
|
100
|
+
"statistics", "run_gfmc", "run",
|
|
101
|
+
"write_to_HDF5", "run_from_HDF5", "evaluate_observables",
|
|
102
|
+
"load_raw_from_HDF5", "check_run_compatible", "resume_from_HDF5",
|
|
103
|
+
]
|
pygfmc/_output.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Printed output of the package.
|
|
2
|
+
|
|
3
|
+
Everything PyGFMC prints passes through :func:`emit`, gated on a caller's
|
|
4
|
+
``verbosity``: a message is printed only when ``verbosity >= level``. The
|
|
5
|
+
drivers pass their ``verbosity`` argument through, so ``verbosity=0`` is
|
|
6
|
+
silent; functions with a boolean switch (``quiet``, ``verbose``) pass it as
|
|
7
|
+
``verbosity=int(flag)``. Set :data:`stream` to redirect every message to a
|
|
8
|
+
file-like object instead of standard output.
|
|
9
|
+
"""
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
#: Destination of every message; ``None`` means ``sys.stdout`` at call time.
|
|
13
|
+
stream = None
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def emit(message, verbosity, level=1, flush=False):
|
|
17
|
+
"""Print ``message`` when ``verbosity >= level``."""
|
|
18
|
+
if verbosity >= level:
|
|
19
|
+
print(message, file=stream if stream is not None else sys.stdout,
|
|
20
|
+
flush=flush)
|
pygfmc/_precision.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""The floating-point width the package computes in: float32, or float64 when
|
|
2
|
+
``jax_enable_x64`` is on (the walkers' weights follow the same switch)."""
|
|
3
|
+
import jax
|
|
4
|
+
import jax.numpy as jnp
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def float_dtype():
|
|
8
|
+
"""``jnp.float64`` when ``jax_enable_x64`` is set, else ``jnp.float32``."""
|
|
9
|
+
return jnp.float64 if jax.config.jax_enable_x64 else jnp.float32
|
pygfmc/_validation.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Argument validation shared by the engine and the Hamiltonian package."""
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
__all__ = ["_validated_int"]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _validated_int(name, value, minimum):
|
|
8
|
+
"""Validate an integer-valued public control parameter."""
|
|
9
|
+
if isinstance(value, (bool, np.bool_)):
|
|
10
|
+
raise ValueError(f"{name} must be an integer >= {minimum}, got {value!r}.")
|
|
11
|
+
try:
|
|
12
|
+
result = int(value)
|
|
13
|
+
is_integral = float(result) == float(value)
|
|
14
|
+
except (TypeError, ValueError, OverflowError):
|
|
15
|
+
is_integral = False
|
|
16
|
+
result = minimum - 1
|
|
17
|
+
if not is_integral or result < minimum:
|
|
18
|
+
raise ValueError(f"{name} must be an integer >= {minimum}, got {value!r}.")
|
|
19
|
+
return result
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""PyGFMC engine: propagation, reconfiguration, estimators and I/O.
|
|
2
|
+
|
|
3
|
+
The deterministic-XLA defaults are set by the top-level :mod:`pygfmc` package,
|
|
4
|
+
which is always imported before this subpackage.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .estimators import statistics
|
|
8
|
+
from .driver import run_gfmc
|
|
9
|
+
from .io import (write_to_HDF5, run_from_HDF5, evaluate_observables,
|
|
10
|
+
load_raw_from_HDF5, check_run_compatible, resume_from_HDF5)
|
|
11
|
+
from .multi_gpu import run
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"statistics", "run_gfmc", "run",
|
|
15
|
+
"write_to_HDF5", "run_from_HDF5", "evaluate_observables",
|
|
16
|
+
"load_raw_from_HDF5", "check_run_compatible", "resume_from_HDF5",
|
|
17
|
+
]
|