Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/spotforecast2/model_selection/spotoptim_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
29 changes: 29 additions & 0 deletions tests/test_spotoptim_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'.

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading