From 67b1a1d815f85d0a761f54364bca7df718707ecf Mon Sep 17 00:00:00 2001 From: bartzbeielstein <32470350+bartzbeielstein@users.noreply.github.com> Date: Sun, 7 Jun 2026 16:27:05 +0200 Subject: [PATCH 1/2] fix(model_selection): create the parallel config-label counter regardless of show_progress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Manager counter for 'config k/N' labels was gated on the outer show_progress flag, but the per-config fold bars are always shown (the objective wrapper hardcodes show_progress=True). The MultiTask pipeline calls spotoptim_search with show_progress=False, so real runs created no counter and the labels froze at 'config 1/N' again — the original bug, reintroduced for exactly the pipeline path. Gate the counter on parallel_eval only; regression test covers the show_progress=False + n_jobs=2 path. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../model_selection/spotoptim_search.py | 7 ++++- tests/test_spotoptim_search.py | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/spotforecast2/model_selection/spotoptim_search.py b/src/spotforecast2/model_selection/spotoptim_search.py index fdf34c5..8ed62b9 100644 --- a/src/spotforecast2/model_selection/spotoptim_search.py +++ b/src/spotforecast2/model_selection/spotoptim_search.py @@ -611,7 +611,12 @@ def spotoptim_search( config_counter = None config_counter_lock = None counter_manager = None - if show_progress and parallel_eval: + # NOT gated on ``show_progress``: the per-config fold bars are always on + # (``_objective_wrapper`` passes ``show_progress=True`` to the objective + # below), so the label needs the shared counter in every parallel run — + # the MultiTask pipeline reaches this with ``show_progress=False`` and + # would otherwise show frozen "config 1/N" labels again. + if parallel_eval: counter_manager = multiprocessing.Manager() config_counter = counter_manager.Value("i", 0) config_counter_lock = counter_manager.Lock() diff --git a/tests/test_spotoptim_search.py b/tests/test_spotoptim_search.py index f12feec..e95604b 100644 --- a/tests/test_spotoptim_search.py +++ b/tests/test_spotoptim_search.py @@ -476,6 +476,35 @@ class FakeCounter: assert descs == ["config 6/10", "config 7/10"] assert counter.value == 7 + def test_parallel_labels_increment_with_show_progress_false( + self, y_series, forecaster, cv, capfd + ): + """Labels must increment even when the OUTER show_progress is False. + + The MultiTask pipeline calls spotoptim_search with + show_progress=False, yet the per-config fold bars are always shown + (the objective wrapper hardcodes show_progress=True). Gating the + shared counter on the outer flag therefore reintroduced frozen + 'config 1/N' labels in every real pipeline run — this is the exact + scenario from the 2026-06-07 team4_submit report. + """ + spotoptim_search( + forecaster=forecaster, + y=y_series, + cv=cv, + search_space={"alpha": (0.01, 10.0)}, + metric="mean_absolute_error", + n_trials=4, + n_initial=2, + return_best=False, + verbose=False, + show_progress=False, + kwargs_spotoptim={"n_jobs": 2}, + ) + err = capfd.readouterr().err + for k in range(1, 5): + assert f"config {k}/4" in err, f"missing 'config {k}/4' in:\n{err}" + def test_parallel_search_labels_increment(self, y_series, forecaster, cv, capfd): """End to end: SpotOptim n_jobs=2 must not repeat 'config 1/N'. From e9e321fde3297b442883edb75aa74768b773d57b Mon Sep 17 00:00:00 2001 From: bartzbeielstein <32470350+bartzbeielstein@users.noreply.github.com> Date: Sun, 7 Jun 2026 16:27:25 +0200 Subject: [PATCH 2/2] chore: refresh uv.lock self-version after 5.1.0 release --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 7dd6068..1fde484 100644 --- a/uv.lock +++ b/uv.lock @@ -3604,7 +3604,7 @@ wheels = [ [[package]] name = "spotforecast2" -version = "5.0.0" +version = "5.1.0" source = { editable = "." } dependencies = [ { name = "astral" },