From c61077d91845235f12b1984c4a0705cc92dd02c0 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 06:42:58 +0000 Subject: [PATCH] docs: make the multi-start batch_size decision explicit A new static check in PyAutoHands flags any MultiStart* search built without an explicit batch_size, because defaulting to None is how both interferometer/start_here.py files inherited an unbounded 48-way vmap on the same day and OOMed two nightly release runs. These four sites keep their current behaviour exactly - None is already the default, so nothing changes at runtime. What changes is that the choice is now written down where a reviewer sees it, with a pointer to the knob if a reader hits a memory limit. Deliberately not given a bounded value: these are CCD imaging, cluster, multi-galaxy and guide likelihoods rather than interferometer ones, and picking a real number needs a measurement on hardware this could not make. imaging/start_here.py is the one most worth profiling later, since a user on a laptop GPU meets it first. Refs PyAutoLabs/PyAutoFit#1452. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0171voyyTrr91hJ3vU5AjeVz --- notebooks/cluster/start_here.ipynb | 1 + notebooks/guides/modeling/searches.ipynb | 1 + notebooks/imaging/start_here.ipynb | 1 + notebooks/multi_galaxy/start_here.ipynb | 1 + scripts/cluster/start_here.py | 1 + scripts/guides/modeling/searches.py | 1 + scripts/imaging/start_here.py | 1 + scripts/multi_galaxy/start_here.py | 1 + 8 files changed, 8 insertions(+) diff --git a/notebooks/cluster/start_here.ipynb b/notebooks/cluster/start_here.ipynb index a66d0a7c..ebd663e6 100644 --- a/notebooks/cluster/start_here.ipynb +++ b/notebooks/cluster/start_here.ipynb @@ -324,6 +324,7 @@ " name=\"start_here\",\n", " unique_tag=dataset_name,\n", " n_starts=48,\n", + " batch_size=None, # Starts evaluated at once: `None` vmaps all 48 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error.\n", " n_steps=300,\n", " iterations_per_quick_update=50,\n", " live_visual_update=False,\n", diff --git a/notebooks/guides/modeling/searches.ipynb b/notebooks/guides/modeling/searches.ipynb index e4343918..886d935e 100644 --- a/notebooks/guides/modeling/searches.ipynb +++ b/notebooks/guides/modeling/searches.ipynb @@ -199,6 +199,7 @@ " path_prefix=Path(\"imaging\", \"searches\"),\n", " name=\"MultiStartProdigy\",\n", " n_starts=50,\n", + " batch_size=None, # Starts evaluated at once: `None` vmaps all 50 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error.\n", " n_steps=500,\n", ")" ], diff --git a/notebooks/imaging/start_here.ipynb b/notebooks/imaging/start_here.ipynb index 3438a284..2c6a6060 100644 --- a/notebooks/imaging/start_here.ipynb +++ b/notebooks/imaging/start_here.ipynb @@ -410,6 +410,7 @@ " name=\"start_here\", # The name of the fit and folder results are output to.\n", " unique_tag=dataset_name, # A unique tag which also defines the folder.\n", " n_starts=48, # The number of independent optimizations run in parallel, increase for more complex models.\n", + " batch_size=None, # Starts evaluated at once: `None` vmaps all 48 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error.\n", " n_steps=300, # The maximum gradient steps per start; the search stops early once the best fit stops improving.\n", " iterations_per_quick_update=50, # Every N steps the max likelihood model is visualized and output.\n", " live_visual_update=False, # Set True to open a live matplotlib window (script) or refresh a Jupyter cell (notebook).\n", diff --git a/notebooks/multi_galaxy/start_here.ipynb b/notebooks/multi_galaxy/start_here.ipynb index 804f9059..067114ec 100644 --- a/notebooks/multi_galaxy/start_here.ipynb +++ b/notebooks/multi_galaxy/start_here.ipynb @@ -306,6 +306,7 @@ " name=\"start_here\",\n", " unique_tag=dataset_name,\n", " n_starts=48,\n", + " batch_size=None, # Starts evaluated at once: `None` vmaps all 48 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error.\n", " n_steps=300,\n", " iterations_per_quick_update=50,\n", " live_visual_update=False,\n", diff --git a/scripts/cluster/start_here.py b/scripts/cluster/start_here.py index 49494307..56dbde5a 100644 --- a/scripts/cluster/start_here.py +++ b/scripts/cluster/start_here.py @@ -237,6 +237,7 @@ name="start_here", unique_tag=dataset_name, n_starts=48, + batch_size=None, # Starts evaluated at once: `None` vmaps all 48 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error. n_steps=300, iterations_per_quick_update=50, live_visual_update=False, diff --git a/scripts/guides/modeling/searches.py b/scripts/guides/modeling/searches.py index d3b80f4f..c530aed4 100644 --- a/scripts/guides/modeling/searches.py +++ b/scripts/guides/modeling/searches.py @@ -129,6 +129,7 @@ path_prefix=Path("imaging", "searches"), name="MultiStartProdigy", n_starts=50, + batch_size=None, # Starts evaluated at once: `None` vmaps all 50 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error. n_steps=500, ) diff --git a/scripts/imaging/start_here.py b/scripts/imaging/start_here.py index 65e364d7..29c2c229 100644 --- a/scripts/imaging/start_here.py +++ b/scripts/imaging/start_here.py @@ -312,6 +312,7 @@ name="start_here", # The name of the fit and folder results are output to. unique_tag=dataset_name, # A unique tag which also defines the folder. n_starts=48, # The number of independent optimizations run in parallel, increase for more complex models. + batch_size=None, # Starts evaluated at once: `None` vmaps all 48 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error. n_steps=300, # The maximum gradient steps per start; the search stops early once the best fit stops improving. iterations_per_quick_update=50, # Every N steps the max likelihood model is visualized and output. live_visual_update=False, # Set True to open a live matplotlib window (script) or refresh a Jupyter cell (notebook). diff --git a/scripts/multi_galaxy/start_here.py b/scripts/multi_galaxy/start_here.py index 921e8ab0..3a80b1f5 100644 --- a/scripts/multi_galaxy/start_here.py +++ b/scripts/multi_galaxy/start_here.py @@ -219,6 +219,7 @@ name="start_here", unique_tag=dataset_name, n_starts=48, + batch_size=None, # Starts evaluated at once: `None` vmaps all 48 together, which is fastest but allocates the whole batched gradient; set an integer (e.g. 4) if you hit an out-of-memory error. n_steps=300, iterations_per_quick_update=50, live_visual_update=False,