Skip to content

Commit f43deff

Browse files
authored
Merge pull request #1158 from rhayes777/feature/build_fixes
Feature/build fixes
2 parents ed4c458 + 13abefd commit f43deff

131 files changed

Lines changed: 874 additions & 757 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

autofit/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
from .non_linear.result import ResultsCollection
9595
from .non_linear.settings import SettingsSearch
9696
from .non_linear.samples.pdf import marginalize
97-
from .example.model import Gaussian, Exponential
9897
from .text import formatter
9998
from .text import samples_text
10099
from .visualise import VisualiseGraph
@@ -129,6 +128,7 @@
129128
"LogUniform",
130129
"Gaussian",
131130
"LogGaussian",
131+
"TruncatedGaussian",
132132
"compound",
133133
"Constant",
134134
):
@@ -142,4 +142,4 @@ def save_abc(pickler, obj):
142142

143143

144144

145-
__version__ = "2025.5.10.1"
145+
__version__ = "2025.10.16.2"

autofit/config/general.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
jax:
22
use_jax: false # If True, PyAutoFit uses JAX internally, whereas False uses normal Numpy.
3-
analysis:
4-
n_cores: 1 # The number of cores a parallelized sum of Analysis classes uses by default.
3+
updates:
4+
iterations_per_quick_update: 1e99 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
5+
iterations_per_full_update: 1e99 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
56
hpc:
67
hpc_mode: false # If True, use HPC mode, which disables GUI visualization, logging to screen and other settings which are not suited to running on a super computer.
7-
iterations_per_update: 5000 # The number of iterations between every update (visualization, results output, etc) in HPC mode.
8+
iterations_per_quick_update: 1e99 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
9+
iterations_per_full_update: 1e99 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
810
inversion:
911
check_reconstruction: true # If True, the inversion's reconstruction is checked to ensure the solution of a meshs's mapper is not an invalid solution where the values are all the same.
1012
reconstruction_vmax_factor: 0.5 # Plots of an Inversion's reconstruction use the reconstructed data's bright value multiplied by this factor.

autofit/config/non_linear/mcmc.yaml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ Emcee:
2626
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
2727
printing:
2828
silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter.
29-
updates:
30-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
31-
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
3229
Zeus:
3330
run:
3431
check_walkers: true
@@ -58,6 +55,6 @@ Zeus:
5855
printing:
5956
silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter.
6057

61-
updates:
62-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
58+
iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
59+
iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
6360
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).

autofit/config/non_linear/mle.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ PySwarmsGlobal:
2424
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
2525
printing:
2626
silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter.
27-
updates:
28-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
27+
iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
28+
iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
2929
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
3030
PySwarmsLocal:
3131
run:
@@ -46,8 +46,8 @@ PySwarmsLocal:
4646
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
4747
printing:
4848
silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter.
49-
updates:
50-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
49+
iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
50+
iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
5151
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
5252
BFGS:
5353
search:
@@ -70,8 +70,8 @@ BFGS:
7070
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
7171
printing:
7272
silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter.
73-
updates:
74-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
73+
iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
74+
iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
7575
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
7676
LBFGS:
7777
search:
@@ -94,8 +94,8 @@ LBFGS:
9494
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
9595
printing:
9696
silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter.
97-
updates:
98-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
97+
iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
98+
iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
9999
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
100100
Drawer:
101101
search:
@@ -108,6 +108,6 @@ Drawer:
108108
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
109109
printing:
110110
silence: false # If True, the default print output of the non-linear search is silcened and not printed by the Python interpreter.
111-
updates:
112-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
111+
iterations_per_full_update: 500 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.
112+
iterations_per_quick_update: 500 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
113113
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).

autofit/config/non_linear/nest.yaml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ DynestyStatic:
3333
force_x1_cpu: false # Force Dynesty to not use Python multiprocessing Pool, which can fix issues on certain operating systems.
3434
printing:
3535
silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter.
36-
updates:
37-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
38-
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
3936
DynestyDynamic:
4037
search:
4138
bootstrap: null
@@ -64,9 +61,6 @@ DynestyDynamic:
6461
force_x1_cpu: false # Force Dynesty to not use Python multiprocessing Pool, which can fix issues on certain operating systems.
6562
printing:
6663
silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter.
67-
updates:
68-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
69-
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
7064
Nautilus:
7165
search:
7266
n_live: 3000 # Number of so-called live points. New bounds are constructed so that they encompass the live points.
@@ -93,9 +87,6 @@ Nautilus:
9387
force_x1_cpu: false # Force Dynesty to not use Python multiprocessing Pool, which can fix issues on certain operating systems.
9488
printing:
9589
silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter.
96-
updates:
97-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
98-
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).
9990
UltraNest:
10091
search:
10192
draw_multiple: true
@@ -140,6 +131,3 @@ UltraNest:
140131
number_of_cores: 1 # The number of cores the search is parallelized over by default, using Python multiprocessing.
141132
printing:
142133
silence: false # If True, the default print output of the non-linear search is silenced and not printed by the Python interpreter.
143-
updates:
144-
iterations_per_update: 500 # The number of iterations of the non-linear search performed between every 'update', where an update performs tasks like outputting model.results.
145-
remove_state_files_at_end: true # Whether to remove the savestate of the seach (e.g. the Emcee hdf5 file) at the end to save hard-disk space (results are still stored as PyAutoFit pickles and loadable).

autofit/example/analysis.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import numpy as np
2+
from typing import Dict, Optional
13

2-
from typing import Dict, List, Optional
3-
4-
from autofit.jax_wrapper import numpy as np
4+
from autofit.jax_wrapper import numpy as xp
55

66
import autofit as af
77

@@ -36,7 +36,7 @@ class Analysis(af.Analysis):
3636
"""
3737
Result = ResultExample
3838

39-
LATENT_KEYS = ["fwhm"]
39+
LATENT_KEYS = ["gaussian.fwhm"]
4040

4141
def __init__(self, data: np.ndarray, noise_map: np.ndarray):
4242
"""
@@ -98,8 +98,8 @@ def model_data_1d_from(self, instance: af.ModelInstance) -> np.ndarray:
9898
The model data of the profiles.
9999
"""
100100

101-
xvalues = np.arange(self.data.shape[0])
102-
model_data_1d = np.zeros(self.data.shape[0])
101+
xvalues = xp.arange(self.data.shape[0])
102+
model_data_1d = xp.zeros(self.data.shape[0])
103103

104104
try:
105105
for profile in instance:

autofit/example/model.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import math
2+
import numpy as np
23
from typing import Tuple
34

4-
from autofit.jax_wrapper import numpy as np
5+
from autofit.jax_wrapper import numpy as xp
56

67
"""
78
The `Gaussian` class in this module is the model components that is fitted to data using a non-linear search. The
@@ -46,7 +47,7 @@ def fwhm(self) -> float:
4647
the free parameters of the model which we are interested and may want to store the full samples information
4748
on (e.g. to create posteriors).
4849
"""
49-
return 2 * np.sqrt(2 * np.log(2)) * self.sigma
50+
return 2 * xp.sqrt(2 * xp.log(2)) * self.sigma
5051

5152
def _tree_flatten(self):
5253
return (self.centre, self.normalization, self.sigma), None
@@ -76,16 +77,16 @@ def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
7677
"""
7778
transformed_xvalues = xvalues - self.centre
7879

79-
return np.multiply(
80-
np.divide(self.normalization, self.sigma * np.sqrt(2.0 * np.pi)),
81-
np.exp(-0.5 * np.square(np.divide(transformed_xvalues, self.sigma))),
80+
return xp.multiply(
81+
xp.divide(self.normalization, self.sigma * xp.sqrt(2.0 * xp.pi)),
82+
xp.exp(-0.5 * xp.square(xp.divide(transformed_xvalues, self.sigma))),
8283
)
8384

8485
def f(self, x: float):
8586
return (
8687
self.normalization
87-
/ (self.sigma * np.sqrt(2 * math.pi))
88-
* np.exp(-0.5 * ((x - self.centre) / self.sigma) ** 2)
88+
/ (self.sigma * xp.sqrt(2 * math.pi))
89+
* xp.exp(-0.5 * ((x - self.centre) / self.sigma) ** 2)
8990
)
9091

9192
def __call__(self, xvalues: np.ndarray) -> np.ndarray:
@@ -147,9 +148,9 @@ def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
147148
values
148149
The x coordinates in the original reference frame of the grid.
149150
"""
150-
transformed_xvalues = np.subtract(xvalues, self.centre)
151-
return self.normalization * np.multiply(
152-
self.rate, np.exp(-1.0 * self.rate * abs(transformed_xvalues))
151+
transformed_xvalues = xp.subtract(xvalues, self.centre)
152+
return self.normalization * xp.multiply(
153+
self.rate, xp.exp(-1.0 * self.rate * abs(transformed_xvalues))
153154
)
154155

155156
def __call__(self, xvalues: np.ndarray) -> np.ndarray:

autofit/fixtures.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
def make_model_gaussian_x1():
88

99
return af.Model(
10-
af.Gaussian
10+
af.ex.Gaussian
1111
)
1212

1313

autofit/jax_wrapper.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,50 @@
1+
import logging
2+
3+
logger = logging.getLogger(__name__)
4+
15
"""
26
Allows the user to switch between using NumPy and JAX for linear algebra operations.
37
48
If USE_JAX=true in general.yaml then JAX's NumPy is used, otherwise vanilla NumPy is used.
59
"""
6-
import jax
7-
810
from autoconf import conf
911

1012
use_jax = conf.instance["general"]["jax"]["use_jax"]
1113

1214
if use_jax:
1315

16+
import os
17+
18+
xla_env = os.environ.get("XLA_FLAGS")
19+
20+
xla_env_set = True
21+
22+
if xla_env is None:
23+
xla_env_set = False
24+
elif isinstance(xla_env, str):
25+
xla_env_set = not "--xla_disable_hlo_passes=constant_folding" in xla_env
26+
27+
28+
if not xla_env_set:
29+
logger.info(
30+
"""
31+
For fast JAX compile times, the envirment variable XLA_FLAGS must be set to "--xla_disable_hlo_passes=constant_folding",
32+
which is currently not.
33+
34+
In Python, to do this manually, use the code:
35+
36+
import os
37+
os.environ["XLA_FLAGS"] = "--xla_disable_hlo_passes=constant_folding"
38+
39+
The environment variable has been set automatically for you now, however if JAX has already been imported,
40+
this change will not take effect and JAX function compiling times may be slow.
41+
42+
Therefore, it is recommended to set this environment variable before running your script, e.g. in your terminal.
43+
""")
44+
45+
os.environ['XLA_FLAGS'] = "--xla_disable_hlo_passes=constant_folding"
46+
47+
import jax
1448
from jax import numpy
1549

1650
print(

autofit/mapper/prior/abstract.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ def from_dict(
233233
)
234234
if id_ is not None:
235235
loaded_ids[id_] = prior
236+
236237
return prior
237238

238239
def dict(self) -> dict:

0 commit comments

Comments
 (0)