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.
Files changed (43) hide show
  1. pygfmc/__init__.py +103 -0
  2. pygfmc/_output.py +20 -0
  3. pygfmc/_precision.py +9 -0
  4. pygfmc/_validation.py +19 -0
  5. pygfmc/engine/__init__.py +17 -0
  6. pygfmc/engine/driver.py +1510 -0
  7. pygfmc/engine/estimators.py +1362 -0
  8. pygfmc/engine/evolution.py +1101 -0
  9. pygfmc/engine/io.py +1540 -0
  10. pygfmc/engine/multi_gpu.py +866 -0
  11. pygfmc/hamiltonian/SpinHalf.py +649 -0
  12. pygfmc/hamiltonian/__init__.py +20 -0
  13. pygfmc/hamiltonian/_common.py +85 -0
  14. pygfmc/hamiltonian/bose_hubbard.py +479 -0
  15. pygfmc/hamiltonian/exact.py +375 -0
  16. pygfmc/hamiltonian/lattice.py +262 -0
  17. pygfmc/hamiltonian/observables.py +174 -0
  18. pygfmc/hamiltonian/plaquette.py +282 -0
  19. pygfmc/hamiltonian/spin.py +438 -0
  20. pygfmc/hamiltonian/toric.py +304 -0
  21. pygfmc/protocols.py +143 -0
  22. pygfmc/walkers/__init__.py +14 -0
  23. pygfmc/walkers/_h5io.py +27 -0
  24. pygfmc/walkers/reconfiguration.py +62 -0
  25. pygfmc/walkers/walker.py +342 -0
  26. pygfmc/wavefunction/__init__.py +20 -0
  27. pygfmc/wavefunction/_layout.py +19 -0
  28. pygfmc/wavefunction/_optional.py +35 -0
  29. pygfmc/wavefunction/_seed.py +19 -0
  30. pygfmc/wavefunction/_tied_params.py +66 -0
  31. pygfmc/wavefunction/cluster_cps.py +702 -0
  32. pygfmc/wavefunction/cluster_mlp.py +512 -0
  33. pygfmc/wavefunction/exact_ground_state.py +289 -0
  34. pygfmc/wavefunction/generic_netket_training.py +473 -0
  35. pygfmc/wavefunction/jastrow_bose_hubbard.py +341 -0
  36. pygfmc/wavefunction/jastrow_spin.py +318 -0
  37. pygfmc/wavefunction/jastrow_spin_half.py +499 -0
  38. pygfmc-0.1.0.dist-info/METADATA +317 -0
  39. pygfmc-0.1.0.dist-info/RECORD +43 -0
  40. pygfmc-0.1.0.dist-info/WHEEL +5 -0
  41. pygfmc-0.1.0.dist-info/licenses/LICENSE +202 -0
  42. pygfmc-0.1.0.dist-info/licenses/NOTICE +4 -0
  43. 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
+ ]