Fix GPU OOM and None-format bugs in script 08

surrogates_gpu.py: auto_batch_size was missing the irfft output buffer
(batch × T × 4 bytes) from its per-surrogate VRAM estimate, causing OOM
on long series (T≈3600). Added the missing term.

08_combined_timeseries.py: write_combined_report crashed with TypeError
when in-sample load failed (keys absent → None). Added _fv() helper that
formats None values as "N/A" instead of failing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root 2026-04-24 07:33:21 +02:00
parent 965870e25a
commit faf43d8b9e
2 changed files with 16 additions and 5 deletions

View file

@ -499,6 +499,16 @@ def make_combined_figure(
# Report
# ---------------------------------------------------------------------------
def _fv(v, fmt: str) -> str:
"""Format a possibly-None float; returns 'N/A' when None/NaN."""
if v is None:
return "N/A"
try:
return format(float(v), fmt)
except (TypeError, ValueError):
return "N/A"
def write_combined_report(
results: dict,
sinusoid_fit: dict,
@ -536,9 +546,9 @@ Surrogates: {args.n_surrogates:,} per window
| Window | p_global | σ_surrogate | peak lag |
|---|---|---|---|
| In-sample (19762019) | {results.get('p_global_insample', float('nan')):.4f} | {results.get('sigma_insample', float('nan')):.2f} | {results.get('peak_lag_insample', '?')} d |
| Out-of-sample (2020{args.study_end[:4]}) | {results.get('p_global_oos', float('nan')):.4f} | {results.get('sigma_oos', float('nan')):.2f} | {results.get('peak_lag_oos', '?')} d |
| Combined (1976{args.study_end[:4]}) | {results.get('p_global_full', float('nan')):.4f} | {results.get('sigma_full', float('nan')):.2f} | {results.get('peak_lag_full', '?')} d |
| In-sample (19762019) | {_fv(results.get('p_global_insample'), '.4f')} | {_fv(results.get('sigma_insample'), '.2f')} | {results.get('peak_lag_insample', 'N/A')} d |
| Out-of-sample (2020{args.study_end[:4]}) | {_fv(results.get('p_global_oos'), '.4f')} | {_fv(results.get('sigma_oos'), '.2f')} | {results.get('peak_lag_oos', 'N/A')} d |
| Combined (1976{args.study_end[:4]}) | {_fv(results.get('p_global_full'), '.4f')} | {_fv(results.get('sigma_full'), '.2f')} | {results.get('peak_lag_full', 'N/A')} d |
## Sinusoidal envelope fit

View file

@ -119,12 +119,13 @@ def auto_batch_size(
+ T * 4 # int32 rank buffer
)
else:
# Phase: tiled signal + sorted copy + rank buffer + rfft
# Phase: tiled signal + sorted copy + rank buffer + rfft + irfft output
bytes_per_surrogate = (
T * bytes_per_elem # signal
+ T * bytes_per_elem # sorted copy
+ T * 4 # int32 rank indices
+ (T // 2 + 1) * 8 # complex64 FFT
+ (T // 2 + 1) * 8 # complex64 FFT coefficients
+ T * bytes_per_elem # irfft output buffer (was missing)
)
budget = vram_budget_gb * 1e9 * (1.0 - headroom)
batch = max(1, int(budget // bytes_per_surrogate))