PyAETNA 4.0.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.
- PyAETNA/__init__.py +9 -0
- PyAETNA/__main__.py +5 -0
- PyAETNA/_device_config.py +57 -0
- PyAETNA/_xla_flags.py +50 -0
- PyAETNA/body_models.py +2336 -0
- PyAETNA/cli.py +52 -0
- PyAETNA/gp.py +791 -0
- PyAETNA/gp_parallel.py +172 -0
- PyAETNA/kernels/factory.py +823 -0
- PyAETNA/kernels/multichannel.py +417 -0
- PyAETNA/logger.py +73 -0
- PyAETNA/model_utils.py +282 -0
- PyAETNA/outputs.py +260 -0
- PyAETNA/physics/__init__.py +6 -0
- PyAETNA/physics/orbital.py +479 -0
- PyAETNA/physics/plotting.py +767 -0
- PyAETNA/physics/priors.py +89 -0
- PyAETNA/physics/spectra.py +483 -0
- PyAETNA/physics/stellar.py +369 -0
- PyAETNA/planet_phys.py +1414 -0
- PyAETNA/provenance.py +163 -0
- PyAETNA/py.typed +0 -0
- PyAETNA/reporting/__init__.py +64 -0
- PyAETNA/reporting/confidence_bands.py +1238 -0
- PyAETNA/reporting/corner_plot.py +1204 -0
- PyAETNA/reporting/data_validation.py +116 -0
- PyAETNA/reporting/diagnostics.py +580 -0
- PyAETNA/reporting/gp_plotting.py +942 -0
- PyAETNA/reporting/grid_builder.py +1257 -0
- PyAETNA/reporting/model_components.py +894 -0
- PyAETNA/reporting/model_math.py +1096 -0
- PyAETNA/reporting/multigp_plots.py +1681 -0
- PyAETNA/reporting/noise_plots.py +406 -0
- PyAETNA/reporting/panel_detrended.py +188 -0
- PyAETNA/reporting/panel_nontime_residuals.py +467 -0
- PyAETNA/reporting/panel_overlay.py +745 -0
- PyAETNA/reporting/panel_residuals.py +109 -0
- PyAETNA/reporting/param_sorting.py +155 -0
- PyAETNA/reporting/pdf_report.py +2119 -0
- PyAETNA/reporting/periodogram_plots.py +1467 -0
- PyAETNA/reporting/phase_plots.py +1529 -0
- PyAETNA/reporting/plot_data_prep.py +1123 -0
- PyAETNA/reporting/plot_models.py +177 -0
- PyAETNA/reporting/plot_styling.py +468 -0
- PyAETNA/reporting/residual_plotting.py +419 -0
- PyAETNA/reporting/trend_detection.py +128 -0
- PyAETNA/reporting/ttv_plots.py +1226 -0
- PyAETNA/run.py +813 -0
- PyAETNA/sampling/__init__.py +19 -0
- PyAETNA/sampling/centering.py +331 -0
- PyAETNA/sampling/config/parser/__init__.py +602 -0
- PyAETNA/sampling/config/parser/_constants.py +14 -0
- PyAETNA/sampling/config/parser/detrending.py +825 -0
- PyAETNA/sampling/config/parser/gp.py +386 -0
- PyAETNA/sampling/config/parser/multigp.py +697 -0
- PyAETNA/sampling/config/parser/ordering.py +154 -0
- PyAETNA/sampling/config/parser/planets.py +699 -0
- PyAETNA/sampling/config/parser/prior_refs.py +157 -0
- PyAETNA/sampling/config/parser/scoping.py +465 -0
- PyAETNA/sampling/config/parser/star.py +647 -0
- PyAETNA/sampling/config/priors.py +266 -0
- PyAETNA/sampling/config/section.py +51 -0
- PyAETNA/sampling/config/validation.py +231 -0
- PyAETNA/sampling/data.py +243 -0
- PyAETNA/sampling/eccentricity.py +65 -0
- PyAETNA/sampling/energy.py +431 -0
- PyAETNA/sampling/engine/checkpoint.py +461 -0
- PyAETNA/sampling/engine/context.py +24 -0
- PyAETNA/sampling/engine/convergence.py +126 -0
- PyAETNA/sampling/engine/data_loader.py +335 -0
- PyAETNA/sampling/engine/eiv.py +458 -0
- PyAETNA/sampling/engine/ensemble_kernels.py +238 -0
- PyAETNA/sampling/engine/exceptions.py +47 -0
- PyAETNA/sampling/engine/execution.py +500 -0
- PyAETNA/sampling/engine/numpyro_model.py +1031 -0
- PyAETNA/sampling/engine/runner.py +150 -0
- PyAETNA/sampling/engine/sampler_settings.py +192 -0
- PyAETNA/sampling/engine/sampler_utils.py +404 -0
- PyAETNA/sampling/engine/sampling_logging.py +292 -0
- PyAETNA/sampling/engine/sampling_utils.py +707 -0
- PyAETNA/sampling/model/core.py +774 -0
- PyAETNA/sampling/model/detrending.py +315 -0
- PyAETNA/sampling/nested_sampling.py +1457 -0
- PyAETNA/sampling/peaks.py +1225 -0
- PyAETNA/sampling/precision.py +393 -0
- PyAETNA/sampling/protocols.py +140 -0
- PyAETNA/sampling/utils.py +299 -0
- PyAETNA/utils/__init__.py +4 -0
- PyAETNA/utils/constants.py +26 -0
- PyAETNA/version.py +21 -0
- pyaetna-4.0.0.dist-info/METADATA +269 -0
- pyaetna-4.0.0.dist-info/RECORD +96 -0
- pyaetna-4.0.0.dist-info/WHEEL +5 -0
- pyaetna-4.0.0.dist-info/entry_points.txt +2 -0
- pyaetna-4.0.0.dist-info/licenses/LICENSE +21 -0
- pyaetna-4.0.0.dist-info/top_level.txt +1 -0
PyAETNA/__init__.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""PyAETNA: JAX-accelerated modelling of exoplanet light curves and radial velocities."""
|
|
2
|
+
|
|
3
|
+
from ._xla_flags import apply_default_xla_flags
|
|
4
|
+
from .version import __version__
|
|
5
|
+
|
|
6
|
+
# Before JAX initialises its GPU backend (see PyAETNA._xla_flags).
|
|
7
|
+
apply_default_xla_flags()
|
|
8
|
+
|
|
9
|
+
__all__ = ["__version__"]
|
PyAETNA/__main__.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Configure JAX device count and BLAS threads for CPU parallelism.
|
|
2
|
+
|
|
3
|
+
This module MUST be imported before any JAX operations to enable multi-core
|
|
4
|
+
CPU parallelism. It sets XLA_FLAGS to create virtual devices for parallel
|
|
5
|
+
MCMC chains.
|
|
6
|
+
|
|
7
|
+
IMPORTANT: This configuration ONLY affects the CPU backend. GPU devices are
|
|
8
|
+
still detected and preferred if available. The --xla_force_host_platform_device_count
|
|
9
|
+
flag does not prevent JAX from using GPUs when present on the system.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
|
|
14
|
+
# Configure host CPU device count for JAX before importing it.
|
|
15
|
+
# Use the machine's CPU count, and at least _MIN_HOST_DEVICES, by default, but
|
|
16
|
+
# allow explicit override via env var PYAETNA_XLA_FORCE_HOST_PLATFORM_DEVICE_COUNT.
|
|
17
|
+
# Nested sampling on a CPU gives each of its slice chains (50 by default) its own
|
|
18
|
+
# device, which is fastest even when there are fewer cores than devices
|
|
19
|
+
# (sampling/nested_sampling.py, cpu_chain_mesh).
|
|
20
|
+
# NOTE: This setting does NOT affect GPU detection or usage.
|
|
21
|
+
_MIN_HOST_DEVICES = 64
|
|
22
|
+
_cpu_count = os.cpu_count() or 1
|
|
23
|
+
_default = max(_cpu_count, _MIN_HOST_DEVICES)
|
|
24
|
+
_override = os.environ.get("PYAETNA_XLA_FORCE_HOST_PLATFORM_DEVICE_COUNT")
|
|
25
|
+
try:
|
|
26
|
+
_n_devices = max(1, int(_override)) if _override is not None else _default
|
|
27
|
+
except ValueError:
|
|
28
|
+
_n_devices = _default
|
|
29
|
+
|
|
30
|
+
# One thread per BLAS/LAPACK call, unless the user set it. On a CPU, JAX runs dense linear algebra (Cholesky
|
|
31
|
+
# factorisations and triangular solves of dense GPs) as LAPACK calls into OpenBLAS; with many host devices
|
|
32
|
+
# calling it at once, a multithreaded OpenBLAS oversubscribes the CPU and its threads contend. On the K2-100
|
|
33
|
+
# multi-GP benchmark (8 logical CPUs, 50 chains on host devices) one thread made nested sampling 65 times
|
|
34
|
+
# faster (98 -> 6.4e3 likelihood evaluations per second). Must be set before NumPy is first imported.
|
|
35
|
+
for _var in ("OPENBLAS_NUM_THREADS", "MKL_NUM_THREADS", "OMP_NUM_THREADS"):
|
|
36
|
+
os.environ.setdefault(_var, "1")
|
|
37
|
+
|
|
38
|
+
_flag = f"--xla_force_host_platform_device_count={_n_devices}"
|
|
39
|
+
_existing = os.environ.get("XLA_FLAGS", "")
|
|
40
|
+
if "--xla_force_host_platform_device_count=" not in _existing:
|
|
41
|
+
os.environ["XLA_FLAGS"] = (_existing + " " + _flag).strip()
|
|
42
|
+
|
|
43
|
+
# Longer timeouts for collectives between host devices, unless the user set them. The slice chains of a
|
|
44
|
+
# nested-sampling iteration meet at an all-gather; XLA aborts the process (SIGABRT) when a device arrives more
|
|
45
|
+
# than ~60 s after the others (warning after 20 s). With 50 chains on few cores and an expensive likelihood a
|
|
46
|
+
# chain can legitimately be that late, so warn after 5 min and abort only after an hour (an interrupted
|
|
47
|
+
# nested-sampling run resumes from its checkpoint). Note (2026-09-30, under investigation): on the laptop, TOI-216
|
|
48
|
+
# (a GP on 196k points, 50 chains on 12 cores) twice stopped with two devices that never reached the all-gather
|
|
49
|
+
# while the CPU was idle, i.e. a deadlock, not a late chain; the same run on 12 cores of the server completed.
|
|
50
|
+
_COLLECTIVE_TIMEOUTS = {
|
|
51
|
+
"--xla_cpu_collective_call_warn_stuck_timeout_seconds": "300",
|
|
52
|
+
"--xla_cpu_collective_call_terminate_timeout_seconds": "3600",
|
|
53
|
+
}
|
|
54
|
+
for _name, _value in _COLLECTIVE_TIMEOUTS.items():
|
|
55
|
+
_existing = os.environ.get("XLA_FLAGS", "")
|
|
56
|
+
if f"{_name}=" not in _existing:
|
|
57
|
+
os.environ["XLA_FLAGS"] = f"{_existing} {_name}={_value}".strip()
|
PyAETNA/_xla_flags.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""XLA compiler flags PyAETNA needs on GPU.
|
|
2
|
+
|
|
3
|
+
Applied when the package is imported, i.e. before JAX initialises its GPU
|
|
4
|
+
backend, which is when ``XLA_FLAGS`` is read. A flag the user already set in
|
|
5
|
+
``XLA_FLAGS`` is never overridden.
|
|
6
|
+
|
|
7
|
+
``--xla_gpu_experimental_enable_fusion_autotuner=false``
|
|
8
|
+
XLA's GPU *fusion* autotuner can explode on some fused kernels once the
|
|
9
|
+
batch is large enough: vectorising the Pi Men likelihood (four
|
|
10
|
+
instruments, 223 RVs) over 500 points drove compilation above 23 GB of
|
|
11
|
+
host RAM until the kernel killed the process. The threshold depends on
|
|
12
|
+
the model and the code version: with JAX 0.11.0 and the eccentric Pi Men
|
|
13
|
+
model, 302 points compile in 1.9 s with 1.7 GB, while 303 were killed at an
|
|
14
|
+
8 GB cap after 64 s. Nested sampling evaluates its 500
|
|
15
|
+
initial live points in one batch, so it hit this directly. Disabling
|
|
16
|
+
only the fusion autotuner removes the problem and leaves GEMM autotuning
|
|
17
|
+
on: on K2-140 and on a dense GP the run time is unchanged (turning off
|
|
18
|
+
all autotuning with ``--xla_gpu_autotune_level=0`` would make a
|
|
19
|
+
small-batch dense GP ~30% slower). To re-enable it, set the flag to
|
|
20
|
+
``true`` in ``XLA_FLAGS`` before importing PyAETNA. Reported upstream as
|
|
21
|
+
https://github.com/openxla/xla/issues/49549 (still present in JAX 0.11.2),
|
|
22
|
+
with a standalone reproducer; possibly related: tue-bmd/zea#599 (compile
|
|
23
|
+
time exploding above a grid size, same workaround). Fixed upstream on
|
|
24
|
+
2026-09-29 by XLA commit c644af1 ("Prevent exponential op duplication in
|
|
25
|
+
TritonXLAFoldTransposePass"): transpose folding cloned the operations of
|
|
26
|
+
reconvergent elementwise graphs into a tree, so compile time and memory
|
|
27
|
+
grew exponentially. Keep the flag until the minimum supported JAX
|
|
28
|
+
includes that commit, then check the reproducer and remove it.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
import os
|
|
34
|
+
|
|
35
|
+
_DEFAULT_FLAGS = {
|
|
36
|
+
"--xla_gpu_experimental_enable_fusion_autotuner": "false",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def apply_default_xla_flags(environ: dict[str, str] | None = None) -> None:
|
|
41
|
+
"""Append PyAETNA's default XLA flags unless the user already set them."""
|
|
42
|
+
env = os.environ if environ is None else environ
|
|
43
|
+
existing = env.get("XLA_FLAGS", "")
|
|
44
|
+
extra = [
|
|
45
|
+
f"{flag}={value}"
|
|
46
|
+
for flag, value in _DEFAULT_FLAGS.items()
|
|
47
|
+
if f"{flag}=" not in existing
|
|
48
|
+
]
|
|
49
|
+
if extra:
|
|
50
|
+
env["XLA_FLAGS"] = " ".join([existing, *extra]).strip()
|