From a3254924a8b06d2983381d2279ba822827918c8a Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 17:39:30 +0100 Subject: [PATCH 01/24] perf(kernel): skip the discarded SoC series, and add a batch entry point Two changes to the kernel, one that pays off immediately and one that lays the groundwork for running a fan-out of scenarios in parallel. 1. Do not compute the per-minute SoC series when nobody reads it (-13%) run_prediction_kernel allocated an n_steps buffer for every scenario and told the kernel to fill it, but a cached run - which is 19,209 of the 25,727 predictions in a plan - discards it immediately (see the `if not cache` block). Filling it cost a round_py per step, and round_py is snprintf+strtod at ~96ns, by far the most expensive thing in the hot loop. soc is never itself rounded, the result only ever fed soc_out, so skipping it cannot change the simulation. 52.8us -> 28.5us per scenario (1.85x), and the 20 scenario benchmark 42.5s -> 36.9s (-13.1%), byte-identical on all 20 and kernel_parity green. 2. pk_run_batch, so a fan-out can be run in one call Adds PkBatchJob/PkBatchResult and pk_run_batch(handle, jobs, n, results, n_threads), sharing pk_run_one with pk_run so there is a single copy of the simulation. Additive: pk_run keeps its signature and PkScenario keeps its layout, and Python probes for the batch symbol (KERNEL_HAS_BATCH), so a binary built before this still loads and runs every scenario the old way. Batched jobs pass soc_out = null. The one thing a caller still wants from the series is the SoC range across a charge window, so the kernel tracks that inline over an optional step range instead, mirroring the predict_soc scan in thread_run_prediction_charge_min_max - materialising a buffer per job would have cost ~84MB on a large batch. Verified bit-identical against a loop of pk_run over 120 scenarios, every field. Threading is present but NOT yet usable, and n_threads should stay 1: the remaining round_py(soc, 1) at the charge-rate curve lookup is load bearing, and snprintf/strtod serialise on the C library's global locale. With constant work per thread it degrades 17x at 8 threads, which is why 4 threads currently measures 0.6x of serial. A per-thread locale (newlocale + uselocale) takes that from 17.3x to 2.2x in isolation and is the next step before the batch path is wired up in Python. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction_kernel.cpp | 220 +++++++++++++++++++++++++++-- apps/predbat/prediction_kernel.py | 50 ++++++- 2 files changed, 254 insertions(+), 16 deletions(-) diff --git a/apps/predbat/prediction_kernel.cpp b/apps/predbat/prediction_kernel.cpp index 1746a6497..3f00d46e2 100644 --- a/apps/predbat/prediction_kernel.cpp +++ b/apps/predbat/prediction_kernel.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #define PK_ABI_VERSION 3 @@ -184,6 +185,60 @@ struct PkResult { int32_t iboost_running_full; }; +// One scenario in a pk_run_batch() call; field order MUST match the ctypes Structure in +// prediction_kernel.py. +// +// This is deliberately a separate type from PkScenario rather than extra fields on it: pk_run keeps +// its existing layout, so a kernel binary predating the batch entry point still loads and runs, and +// Python falls back to looping pk_run when pk_run_batch is absent. +// +// soc_out may be null. A batched scenario is always a cached (non-saving) run, whose caller discards +// the per-minute SoC series, and materialising one buffer per job would cost ~84MB on a large batch. +// The one thing callers do want from the series is the SoC range across a charge window, so the +// kernel tracks that inline over [soc_range_start_step, soc_range_end_step] instead - set +// soc_range_start_step < 0 to skip it. +struct PkBatchJob { + const double *charge_limit; + const int32_t *charge_start; + const int32_t *charge_end; + const double *export_limits; + const int32_t *export_start; + const int32_t *export_end; + double *soc_out; // optional, null to skip + + int32_t n_charge; + int32_t n_export; + int32_t pv_scenario; + int32_t end_record; + int32_t step; + int32_t soc_range_start_step; // <0 to skip the SoC range scan + int32_t soc_range_end_step; // inclusive +}; + +// Result for one batched scenario; field order MUST match the ctypes Structure in +// prediction_kernel.py. soc_range_min/max mirror thread_run_prediction_charge_min_max's scan over +// predict_soc and are only meaningful when the job asked for a range. +struct PkBatchResult { + PkResult result; + double soc_range_min; + double soc_range_max; + int32_t status; // 0 = ok, matching pk_run's return codes otherwise + int32_t pad; +}; + +// Reusable per-simulation scratch buffers. +// +// build_window_membership assigns n_steps entries and the clip helpers clear-then-push, so all of +// these can be reused across scenarios without reallocating - which matters a lot under threading: +// each scenario would otherwise heap-allocate ~70KB, and 1200 of those per batch put every worker +// thread in contention on the allocator. Measured 4 threads at 0.6x of serial before this, because +// the simulation is cheap enough that malloc, not arithmetic, was the bottleneck. +struct PkScratch { + std::vector charge_member, export_member; + std::vector clipped_start, clipped_end; + std::vector clipped_limit; +}; + // Deep-copied context storage so Python-side buffers can be freed after create struct ContextStore { std::vector rate_import, rate_export, alert_keep; @@ -422,20 +477,37 @@ void pk_context_free(int64_t handle) // Run one prediction scenario. Returns 0 on success, non-zero on error. // Mirrors the hot loop of Prediction.run_prediction() (prediction.py:385-1200) for the // supported configuration: save=None, debug off, step=5 (cars, iBoost and carbon included). -int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) +// Look up a context by handle, or null when the handle is unknown. The returned pointer stays valid +// as long as the caller does not free the context concurrently, which no caller does: contexts are +// created once per plan and released by a weakref finaliser once the Prediction is gone. +static const PkContext *lookup_context(int64_t handle) { - const PkContext *c; - { - std::lock_guard lock(g_context_mutex); - auto it = g_contexts.find(handle); - if (it == g_contexts.end()) { - return 1; - } - c = &it->second->ctx; + std::lock_guard lock(g_context_mutex); + auto it = g_contexts.find(handle); + if (it == g_contexts.end()) { + return nullptr; } + return &it->second->ctx; +} + +// Simulate one scenario against an already-resolved context. +// +// Shared by pk_run and pk_run_batch, and safe to call concurrently on one context: c is const, every +// working value below is a local, and results go only to the caller's own out/soc_range slots. +// +// soc_out may be null (see PkBatchJob). soc_range_min/max are optional out-params: when non-null and +// soc_range_start_step >= 0, they receive the min/max of the rounded SoC over that inclusive step +// range, mirroring the predict_soc scan in Prediction.thread_run_prediction_charge_min_max. +static int32_t pk_run_one(const PkContext *c, const PkScenario *s, PkResult *out, int32_t soc_range_start_step, int32_t soc_range_end_step, double *soc_range_min_out, double *soc_range_max_out, PkScratch &scratch) +{ if (!s || !out || s->step != 5) { return 2; } + // Seeded to match Prediction.thread_run_prediction_charge_min_max, which starts min at soc_max + // and max at 0 so a range covering no recorded step leaves them in that state + double soc_range_min = c->soc_max; + double soc_range_max = 0.0; + const bool want_soc_range = soc_range_start_step >= 0; const int32_t pv_scenario = s->pv_scenario; const bool is_pv10 = pv_scenario == 1; @@ -445,12 +517,14 @@ int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) const bool inverter_hybrid = c->inverter_hybrid != 0; // Window membership - prediction.py:494-495 / find_charge_window_optimised - std::vector charge_window_optimised, export_window_optimised; + std::vector &charge_window_optimised = scratch.charge_member; + std::vector &export_window_optimised = scratch.export_member; // The caller hands over the raw charge windows; clipping them against the export windows used to // be done in Python on every simulation, which cost more than the simulation itself - std::vector clipped_start, clipped_end; - std::vector clipped_limit; + std::vector &clipped_start = scratch.clipped_start; + std::vector &clipped_end = scratch.clipped_end; + std::vector &clipped_limit = scratch.clipped_limit; clip_intersecting_charge_windows(clipped_start, clipped_end, clipped_limit, s->n_charge, s->charge_start, s->charge_end, s->charge_limit, s->n_export, s->export_start, s->export_end, s->export_limits); const int32_t n_charge_clipped = static_cast(clipped_start.size()); @@ -570,8 +644,28 @@ int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) record = false; } - // Save SoC prediction data - prediction.py:627-628 (kernel always fills the buffer) - s->soc_out[k] = round_py(soc, 3); + // Save SoC prediction data - prediction.py:627-628. Batched scenarios pass a null buffer + // (their caller discards the series); the rounded value is still what feeds the SoC range, + // so the range matches a Python scan over predict_soc exactly. + // round_py is snprintf+strtod, ~96ns and by far the most expensive thing in this loop, so it + // is only paid when something actually consumes the value. soc itself is never rounded - the + // result feeds soc_out and the SoC range and nothing else - so skipping it when a batched + // scenario wants neither cannot change the simulation. + const bool in_soc_range = want_soc_range && k >= soc_range_start_step && k <= soc_range_end_step; + if (s->soc_out || in_soc_range) { + const double soc_rounded = round_py(soc, 3); + if (s->soc_out) { + s->soc_out[k] = soc_rounded; + } + if (in_soc_range) { + if (soc_rounded < soc_range_min) { + soc_range_min = soc_rounded; + } + if (soc_rounded > soc_range_max) { + soc_range_max = soc_rounded; + } + } + } // Get load and pv forecast - prediction.py:657-659 double pv_now = pv_step[k]; @@ -1074,7 +1168,105 @@ int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) out->iboost_running = iboost_running; out->iboost_running_solar = iboost_running_solar; out->iboost_running_full = iboost_running_full; + if (soc_range_min_out) { + // Mirrors the two clamping lines that follow the scan in + // thread_run_prediction_charge_min_max, so an empty range collapses to a single value + // rather than leaving min above max + const double clamped_max = soc_range_max > soc_range_min ? soc_range_max : soc_range_min; + const double clamped_min = soc_range_min < clamped_max ? soc_range_min : clamped_max; + *soc_range_min_out = clamped_min; + *soc_range_max_out = clamped_max; + } + return 0; +} + +// Run one scenario. Kept with its original signature and struct so a binary built before the batch +// entry point existed still satisfies the loader and every single-scenario caller. +int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) +{ + const PkContext *c = lookup_context(handle); + if (!c) { + return 1; + } + PkScratch scratch; + return pk_run_one(c, s, out, -1, -1, nullptr, nullptr, scratch); +} + +// Run n_jobs scenarios against one context in a single call. +// +// The point is to pay the Python/C boundary and the context lookup once for a whole fan-out of +// scenarios instead of once each: the per-call Python around pk_run measured ~31us against ~55us of +// simulation, and neither Python threads nor a process pool can recover it (the GIL serialises the +// former, pickling the latter). +// +// Per-job failures are reported in that job's status field rather than aborting the batch, so one +// malformed scenario cannot discard the rest of the fan-out. +// Simulate one batched scenario into its result slot. Split out so the serial and threaded paths +// below share exactly one copy of the marshalling. +static void run_batch_job(const PkContext *c, const PkBatchJob &job, PkBatchResult &out, PkScratch &scratch) +{ + PkScenario scenario; + scenario.charge_limit = job.charge_limit; + scenario.charge_start = job.charge_start; + scenario.charge_end = job.charge_end; + scenario.export_limits = job.export_limits; + scenario.export_start = job.export_start; + scenario.export_end = job.export_end; + scenario.soc_out = job.soc_out; + scenario.n_charge = job.n_charge; + scenario.n_export = job.n_export; + scenario.pv_scenario = job.pv_scenario; + scenario.end_record = job.end_record; + scenario.step = job.step; + out.soc_range_min = 0.0; + out.soc_range_max = 0.0; + out.pad = 0; + out.status = pk_run_one(c, &scenario, &out.result, job.soc_range_start_step, job.soc_range_end_step, &out.soc_range_min, &out.soc_range_max, scratch); +} + +// Run n_jobs scenarios against one context in a single call. +// +// The context lookup and the Python/C boundary are paid once for a whole fan-out rather than once +// per scenario, but the real point is n_threads: 19209 separate ctypes calls cannot be parallelised +// usefully from Python (the GIL serialises threads, and a process pool pays pickling), whereas one +// batch can split the work across cores with no GIL involved at all. +// +// n_threads <= 1 runs serially. Per-job failures land in that job's status field rather than +// aborting the batch, so one malformed scenario cannot discard the rest of the fan-out. +int32_t pk_run_batch(int64_t handle, const PkBatchJob *jobs, int32_t n_jobs, PkBatchResult *results, int32_t n_threads) +{ + const PkContext *c = lookup_context(handle); + if (!c) { + return 1; + } + if (!jobs || !results || n_jobs < 0) { + return 2; + } + // Scenarios are independent - each reads the shared const context and writes only its own result + // slot - so they are split across threads by stride. + if (n_threads > 1 && n_jobs > 1) { + const int32_t use = n_threads < n_jobs ? n_threads : n_jobs; + std::vector pool; + pool.reserve(use); + for (int32_t t = 0; t < use; t++) { + pool.emplace_back([c, jobs, results, n_jobs, use, t]() { + PkScratch scratch; + for (int32_t i = t; i < n_jobs; i += use) { + run_batch_job(c, jobs[i], results[i], scratch); + } + }); + } + for (auto &th : pool) { + th.join(); + } + return 0; + } + PkScratch scratch; + for (int32_t i = 0; i < n_jobs; i++) { + run_batch_job(c, jobs[i], results[i], scratch); + } return 0; } + } // extern "C" diff --git a/apps/predbat/prediction_kernel.py b/apps/predbat/prediction_kernel.py index 2275e9951..7d90317cd 100644 --- a/apps/predbat/prediction_kernel.py +++ b/apps/predbat/prediction_kernel.py @@ -41,6 +41,9 @@ KERNEL_LIB = None KERNEL_LOAD_TRIED = False KERNEL_STATUS = "not loaded" +# True when the loaded binary exposes pk_run_batch. Probed rather than required so a kernel built +# before the batch entry point existed still runs every scenario through the single-call path. +KERNEL_HAS_BATCH = False class PkContext(ctypes.Structure): @@ -176,6 +179,39 @@ class PkResult(ctypes.Structure): ] +class PkBatchJob(ctypes.Structure): + """ctypes mirror of the PkBatchJob struct in prediction_kernel.cpp (field order must match exactly)""" + + _fields_ = [ + ("charge_limit", ctypes.POINTER(ctypes.c_double)), + ("charge_start", ctypes.POINTER(ctypes.c_int32)), + ("charge_end", ctypes.POINTER(ctypes.c_int32)), + ("export_limits", ctypes.POINTER(ctypes.c_double)), + ("export_start", ctypes.POINTER(ctypes.c_int32)), + ("export_end", ctypes.POINTER(ctypes.c_int32)), + ("soc_out", ctypes.POINTER(ctypes.c_double)), + ("n_charge", ctypes.c_int32), + ("n_export", ctypes.c_int32), + ("pv_scenario", ctypes.c_int32), + ("end_record", ctypes.c_int32), + ("step", ctypes.c_int32), + ("soc_range_start_step", ctypes.c_int32), + ("soc_range_end_step", ctypes.c_int32), + ] + + +class PkBatchResult(ctypes.Structure): + """ctypes mirror of the PkBatchResult struct in prediction_kernel.cpp (field order must match exactly)""" + + _fields_ = [ + ("result", PkResult), + ("soc_range_min", ctypes.c_double), + ("soc_range_max", ctypes.c_double), + ("status", ctypes.c_int32), + ("pad", ctypes.c_int32), + ] + + def kernel_library_candidates(): """Return the ordered list of shared library paths to try loading. @@ -220,7 +256,7 @@ def load_kernel(log=None): The result is cached module-wide (including across forked workers); failures are logged once and result in a permanent fallback to the Python engine. """ - global KERNEL_LIB, KERNEL_LOAD_TRIED, KERNEL_STATUS + global KERNEL_LIB, KERNEL_LOAD_TRIED, KERNEL_STATUS, KERNEL_HAS_BATCH if KERNEL_LOAD_TRIED: return KERNEL_LIB @@ -248,6 +284,12 @@ def load_kernel(log=None): lib.pk_context_free.argtypes = [ctypes.c_int64] lib.pk_run.restype = ctypes.c_int32 lib.pk_run.argtypes = [ctypes.c_int64, ctypes.POINTER(PkScenario), ctypes.POINTER(PkResult)] + try: + lib.pk_run_batch.restype = ctypes.c_int32 + lib.pk_run_batch.argtypes = [ctypes.c_int64, ctypes.POINTER(PkBatchJob), ctypes.c_int32, ctypes.POINTER(PkBatchResult)] + KERNEL_HAS_BATCH = True + except AttributeError: + KERNEL_HAS_BATCH = False KERNEL_LIB = lib KERNEL_STATUS = "loaded from {}".format(path) if log: @@ -523,7 +565,11 @@ def run_prediction_kernel(pred, charge_limit, charge_window, export_window, expo scenario.export_limits = double_array(export_limits) scenario.export_start = int32_array([window["start"] for window in export_window]) scenario.export_end = int32_array([window["end"] for window in export_window]) - soc_out = (ctypes.c_double * n_steps)() + # A cached run discards the per-minute SoC series (see the `if not cache` block below), so the + # buffer is not allocated and the kernel is told to skip filling it. That skips a round_py per + # step, which is snprintf+strtod and the single most expensive thing in the kernel's hot loop - + # measured 52.8us -> 28.5us per scenario, for a value that was being thrown away. + soc_out = (ctypes.c_double * n_steps)() if not cache else None scenario.soc_out = soc_out scenario.n_charge = len(charge_window) scenario.n_export = len(export_window) From 2e71022e7f610155e787b045adfa9d8772c48ca6 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 17:50:39 +0100 Subject: [PATCH 02/24] perf(kernel): replace the hot-loop round_py with precomputed SoC percent buckets round_py is snprintf+strtod, ~96ns, and was the most expensive thing in the simulation loop. It survives in the loop for one reason: prediction.py rounds SoC to 1dp before the charge/discharge rate curve lookup. That rounding is not a modelling decision. It exists so utils.get_charge_rate_curve_cached's lru_cache key quantises and the cache hits - a Python memoisation device. The kernel has no such cache and gains nothing from it, but rounding before the percent is taken occasionally moves the resulting integer, so it is observable and parity forced the kernel to reproduce it. Everything downstream only wants an integer 0-100: round(soc,1) -> calc_percent_limit -> curve[percent]. That map is monotone onto 101 buckets, so the boundaries can be found once and the loop reduced to a binary search over them. The boundaries are located by bisecting the double's bit pattern (non-negative doubles order the same as their bits read as integers), so each one is the true boundary to the last bit rather than an approximation. This is exact, not approximate: pk_verify_soc_percent_table sweeps 2,000,000 SoC values plus five probes around all 101 boundaries - where a disagreement would actually hide - for ten battery sizes from 2 to 100 kWh. Zero disagreements. Per scenario, on a 1200 scenario batch: 52.8us original 28.5us after skipping the discarded SoC series 10.9us now 4.8x on serial and it unblocks parallelism, because the contention was libc's global locale inside snprintf/strtod, not the simulation: 1 thread 13.0 ms 2 threads 6.7 ms 1.9x 4 threads 3.5 ms 3.8x 8 threads 2.4 ms 5.4x 16 threads 1.9 ms 6.7x bit-identical at every thread count The 20 scenario benchmark is 36.9s -> 31.6s even before the Python side batches anything, byte-identical on all 20, and kernel_parity passes. No ABI change: the bucket table lives on ContextStore, which never crosses the Python boundary, so PkContext keeps its layout. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction_kernel.cpp | 147 ++++++++++++++++++++++++++--- 1 file changed, 134 insertions(+), 13 deletions(-) diff --git a/apps/predbat/prediction_kernel.cpp b/apps/predbat/prediction_kernel.cpp index 3f00d46e2..18d8840a5 100644 --- a/apps/predbat/prediction_kernel.cpp +++ b/apps/predbat/prediction_kernel.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,71 @@ int32_t calc_percent_limit(double charge_limit, double soc_max) return std::min(static_cast((charge_limit / soc_max * 100.0) + 0.5), 100); } +// The SoC percent that Python's round(soc, 1) -> calc_percent_limit() pair produces. +// +// The 1dp rounding is not a modelling decision - it is there so utils.get_charge_rate_curve_cached's +// lru_cache hits - but rounding before the percent is taken occasionally moves the integer, so the +// kernel has to reproduce it exactly. +int32_t percent_via_round(double soc, double soc_max) +{ + return calc_percent_limit(round_py(soc, 1), soc_max); +} + +// Smallest SoC whose percent_via_round() reaches p, found by bisecting the double's bit pattern. +// +// Non-negative doubles compare in the same order as their bit patterns read as integers, so this is +// an exact bisection over every representable value in the bracket rather than an approximation: +// the boundary it returns is the true one, to the last bit. +double smallest_soc_for_percent(double soc_max, int32_t p, double hi_d) +{ + if (percent_via_round(0.0, soc_max) >= p) { + return 0.0; + } + if (percent_via_round(hi_d, soc_max) < p) { + return std::numeric_limits::infinity(); + } + uint64_t lo_bits, hi_bits; + double lo_d = 0.0; + std::memcpy(&lo_bits, &lo_d, sizeof(lo_bits)); + std::memcpy(&hi_bits, &hi_d, sizeof(hi_bits)); + while (hi_bits - lo_bits > 1) { + const uint64_t mid_bits = lo_bits + (hi_bits - lo_bits) / 2; + double mid_d; + std::memcpy(&mid_d, &mid_bits, sizeof(mid_d)); + if (percent_via_round(mid_d, soc_max) >= p) { + hi_bits = mid_bits; + } else { + lo_bits = mid_bits; + } + } + double result; + std::memcpy(&result, &hi_bits, sizeof(result)); + return result; +} + +// Boundaries of the 101 SoC percent buckets, so the hot loop can map SoC to percent with a binary +// search over doubles instead of a round_py (snprintf + strtod, ~96ns and the most expensive thing +// in the loop - and unusable under threading, since it serialises on the C library's global locale). +// out[p] is the smallest SoC that reads as p percent; out[0] is unused. +void build_soc_percent_thresholds(std::vector &out, double soc_max) +{ + out.assign(101, 0.0); + if (soc_max <= 0) { + return; + } + const double hi = soc_max * 2.0 + 1.0; + for (int32_t p = 1; p <= 100; p++) { + out[p] = smallest_soc_for_percent(soc_max, p, hi); + } + // upper_bound needs a non-decreasing sequence; the map is monotone so this only guards against + // an unreachable percent leaving an infinity in front of a later finite entry + for (int32_t p = 2; p <= 100; p++) { + if (out[p] < out[p - 1]) { + out[p] = out[p - 1]; + } + } +} + // Per-plan static context passed from Python, arrays are all n_steps long // (index k covers relative minute k*5) unless stated otherwise. // Field order MUST match the ctypes Structure in prediction_kernel.py exactly. @@ -248,6 +314,7 @@ struct ContextStore { std::vector charge_curve, discharge_curve; std::vector carbon, gas_rate, iboost_plan_load; std::vector car_load_flat, car_rate_flat; + std::vector soc_percent_threshold; // see build_soc_percent_thresholds PkContext ctx; }; @@ -277,6 +344,14 @@ inline double get_total_inverted(double battery_draw, double pv_dc, double pv_ac // Mirror of utils.py get_charge_rate_curve_cached()/get_discharge_rate_curve_cached(). // soc_key is passed exactly as Python does (usually round(soc, 1), but raw soc for the DC-rate lookups). // temp_cap_base is the pre-computed find_battery_temperature_cap() value before the min with max_rate. +inline double rate_curve_pct(int32_t soc_percent, double rate_setting, double rate_max, double temp_cap_base, const double *curve, double rate_min) +{ + double max_rate = rate_max * curve[soc_percent]; + double max_rate_cap = std::min(temp_cap_base, rate_max); + max_rate = std::min(max_rate, max_rate_cap); + return std::max(std::min(rate_setting, max_rate), rate_min); +} + inline double rate_curve(double soc_key, double rate_setting, double rate_max, double temp_cap_base, const double *curve, double soc_max, double rate_min) { int32_t soc_percent = calc_percent_limit(soc_key, soc_max); @@ -417,6 +492,7 @@ int64_t pk_context_create(const PkContext *in) return 0; } auto store = std::make_unique(); + build_soc_percent_thresholds(store->soc_percent_threshold, in->soc_max); size_t n = static_cast(in->n_steps); store->rate_import.assign(in->rate_import, in->rate_import + n); store->rate_export.assign(in->rate_export, in->rate_export + n); @@ -480,14 +556,14 @@ void pk_context_free(int64_t handle) // Look up a context by handle, or null when the handle is unknown. The returned pointer stays valid // as long as the caller does not free the context concurrently, which no caller does: contexts are // created once per plan and released by a weakref finaliser once the Prediction is gone. -static const PkContext *lookup_context(int64_t handle) +static const ContextStore *lookup_context(int64_t handle) { std::lock_guard lock(g_context_mutex); auto it = g_contexts.find(handle); if (it == g_contexts.end()) { return nullptr; } - return &it->second->ctx; + return it->second.get(); } // Simulate one scenario against an already-resolved context. @@ -498,8 +574,10 @@ static const PkContext *lookup_context(int64_t handle) // soc_out may be null (see PkBatchJob). soc_range_min/max are optional out-params: when non-null and // soc_range_start_step >= 0, they receive the min/max of the rounded SoC over that inclusive step // range, mirroring the predict_soc scan in Prediction.thread_run_prediction_charge_min_max. -static int32_t pk_run_one(const PkContext *c, const PkScenario *s, PkResult *out, int32_t soc_range_start_step, int32_t soc_range_end_step, double *soc_range_min_out, double *soc_range_max_out, PkScratch &scratch) +static int32_t pk_run_one(const ContextStore *store, const PkScenario *s, PkResult *out, int32_t soc_range_start_step, int32_t soc_range_end_step, double *soc_range_min_out, double *soc_range_max_out, PkScratch &scratch) { + const PkContext *c = &store->ctx; + const std::vector &soc_pct_threshold = store->soc_percent_threshold; if (!s || !out || s->step != 5) { return 2; } @@ -794,11 +872,14 @@ static int32_t pk_run_one(const PkContext *c, const PkScenario *s, PkResult *out } } - // Current real charge rate - prediction.py:777-786 - const double soc_round1 = round_py(soc, 1); - double charge_rate_now_curve = rate_curve(soc_round1, charge_rate_now, battery_rate_max_charge, c->temp_charge_cap[k], c->charge_curve, soc_max, battery_rate_min) * battery_rate_max_scaling; + // Current real charge rate - prediction.py:777-786. + // Python rounds SoC to 1dp here purely to quantise an lru_cache key, but the rounding moves + // the percent at bucket edges so it is observable. The precomputed bucket boundaries give + // the identical percent from a binary search, with no round_py in the loop at all. + const int32_t soc_percent_round1 = soc >= 0.0 ? static_cast(std::upper_bound(soc_pct_threshold.begin() + 1, soc_pct_threshold.end(), soc) - (soc_pct_threshold.begin() + 1)) : percent_via_round(soc, soc_max); + double charge_rate_now_curve = rate_curve_pct(soc_percent_round1, charge_rate_now, battery_rate_max_charge, c->temp_charge_cap[k], c->charge_curve, battery_rate_min) * battery_rate_max_scaling; double charge_rate_now_curve_step = charge_rate_now_curve * step; - double discharge_rate_now_curve = rate_curve(soc_round1, discharge_rate_now, battery_rate_max_discharge, c->temp_discharge_cap[k], c->discharge_curve, soc_max, battery_rate_min) * battery_rate_max_scaling_discharge; + double discharge_rate_now_curve = rate_curve_pct(soc_percent_round1, discharge_rate_now, battery_rate_max_discharge, c->temp_discharge_cap[k], c->discharge_curve, battery_rate_min) * battery_rate_max_scaling_discharge; double discharge_rate_now_curve_step = discharge_rate_now_curve * step; const double battery_to_min = std::max(soc - reserve_expected, 0.0) * battery_loss_discharge; @@ -821,7 +902,7 @@ static int32_t pk_run_one(const PkContext *c, const PkScenario *s, PkResult *out export_rate_adjust = 1 - (export_limit_now - static_cast(static_cast(export_limit_now))); } discharge_rate_now = battery_rate_max_export * export_rate_adjust; - discharge_rate_now_curve = rate_curve(soc_round1, discharge_rate_now, battery_rate_max_export, c->temp_discharge_cap[k], c->discharge_curve, soc_max, battery_rate_min) * battery_rate_max_scaling_discharge; + discharge_rate_now_curve = rate_curve_pct(soc_percent_round1, discharge_rate_now, battery_rate_max_export, c->temp_discharge_cap[k], c->discharge_curve, battery_rate_min) * battery_rate_max_scaling_discharge; discharge_rate_now_curve_step = discharge_rate_now_curve * step; battery_draw = std::min(discharge_rate_now_curve_step, battery_to_min); @@ -907,7 +988,7 @@ static int32_t pk_run_one(const PkContext *c, const PkScenario *s, PkResult *out // find_charge_rate with set_charge_low_power off (always the case for scenario runs) // reduces to the max rate and its curve value - utils.py:1145,1237-1238 charge_rate_now = battery_rate_max_charge_combined; - charge_rate_now_curve = rate_curve(soc_round1, battery_rate_max_charge_combined, battery_rate_max_charge_combined, c->temp_charge_cap[k], c->charge_curve, soc_max, battery_rate_min) * battery_rate_max_scaling; + charge_rate_now_curve = rate_curve_pct(soc_percent_round1, battery_rate_max_charge_combined, battery_rate_max_charge_combined, c->temp_charge_cap[k], c->charge_curve, battery_rate_min) * battery_rate_max_scaling; charge_rate_now_curve_step = charge_rate_now_curve * step; battery_draw = -std::max({std::min(charge_rate_now_curve_step, std::max(charge_limit_n - soc, pv_now)), 0.0, -battery_to_max}); @@ -1184,12 +1265,12 @@ static int32_t pk_run_one(const PkContext *c, const PkScenario *s, PkResult *out // entry point existed still satisfies the loader and every single-scenario caller. int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) { - const PkContext *c = lookup_context(handle); + const ContextStore *c = lookup_context(handle); if (!c) { return 1; } PkScratch scratch; - return pk_run_one(c, s, out, -1, -1, nullptr, nullptr, scratch); + return pk_run_one(c, s, out, -1, -1, nullptr, nullptr, scratch); // c is the store } // Run n_jobs scenarios against one context in a single call. @@ -1203,7 +1284,7 @@ int32_t pk_run(int64_t handle, const PkScenario *s, PkResult *out) // malformed scenario cannot discard the rest of the fan-out. // Simulate one batched scenario into its result slot. Split out so the serial and threaded paths // below share exactly one copy of the marshalling. -static void run_batch_job(const PkContext *c, const PkBatchJob &job, PkBatchResult &out, PkScratch &scratch) +static void run_batch_job(const ContextStore *c, const PkBatchJob &job, PkBatchResult &out, PkScratch &scratch) { PkScenario scenario; scenario.charge_limit = job.charge_limit; @@ -1235,7 +1316,7 @@ static void run_batch_job(const PkContext *c, const PkBatchJob &job, PkBatchResu // aborting the batch, so one malformed scenario cannot discard the rest of the fan-out. int32_t pk_run_batch(int64_t handle, const PkBatchJob *jobs, int32_t n_jobs, PkBatchResult *results, int32_t n_threads) { - const PkContext *c = lookup_context(handle); + const ContextStore *c = lookup_context(handle); if (!c) { return 1; } @@ -1269,4 +1350,44 @@ int32_t pk_run_batch(int64_t handle, const PkBatchJob *jobs, int32_t n_jobs, PkB } +// Test hook: sweep SoC densely and confirm the precomputed bucket boundaries give exactly the same +// percent as the round_py path they replace. Returns the number of disagreements (0 = equivalent). +int32_t pk_verify_soc_percent_table(double soc_max, int32_t samples) +{ + std::vector table; + build_soc_percent_thresholds(table, soc_max); + int32_t bad = 0; + const double hi = soc_max * 1.2 + 0.5; + for (int32_t i = 0; i <= samples; i++) { + const double soc = hi * static_cast(i) / static_cast(samples); + const int32_t want = percent_via_round(soc, soc_max); + const int32_t got = static_cast(std::upper_bound(table.begin() + 1, table.end(), soc) - (table.begin() + 1)); + if (want != got) { + bad++; + } + } + // Also probe either side of every boundary, where a disagreement would actually hide + for (int32_t p = 1; p <= 100; p++) { + const double edge = table[p]; + if (!std::isfinite(edge)) { + continue; + } + for (int32_t d = -2; d <= 2; d++) { + double probe = edge; + for (int32_t n = 0; n < std::abs(d); n++) { + probe = d < 0 ? std::nextafter(probe, -1.0) : std::nextafter(probe, 1e18); + } + if (probe < 0) { + continue; + } + const int32_t want = percent_via_round(probe, soc_max); + const int32_t got = static_cast(std::upper_bound(table.begin() + 1, table.end(), probe) - (table.begin() + 1)); + if (want != got) { + bad++; + } + } + } + return bad; +} + } // extern "C" From be2510d0c171d47a6d2bc9253a84f04ed8294e59 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 18:23:11 +0100 Subject: [PATCH 03/24] test(kernel): pin the SoC percent table, and rebuild the shipped binaries Adds run_soc_percent_table_tests to the kernel parity suite. It drives the kernel's own pk_verify_soc_percent_table over eleven battery sizes from 0.5 to 100 kWh, sweeping the SoC range and - the part that matters - probing either side of all 101 bucket boundaries, since a boundary is the only place the table could disagree with the round_py path it replaced. Checked that the test actually bites: nudging a single boundary by one ULP makes it fail on five of the eleven capacities, so it detects the smallest corruption the table can have rather than only catching gross breakage. Also rebuilds all six shipped binaries, which were built before the batch entry point and the bucket table existed. Verified the new symbols are present in every one (dynamic symbols for the four stripped Linux ELFs, nm for the two Mach-O), and loaded the cross-built darwin_arm64 directly to confirm it reports the batch entry point and agrees with round_py on the table. Without this a non-macOS install would silently fall back to the Python engine. Co-Authored-By: Claude Opus 5 (1M context) --- .cspell/custom-dictionary-workspace.txt | 2 ++ apps/predbat/prediction_kernel_lib_aarch64.so | Bin 238832 -> 247200 bytes apps/predbat/prediction_kernel_lib_armv7l.so | Bin 190808 -> 197840 bytes .../prediction_kernel_lib_darwin_arm64.so | Bin 301208 -> 304200 bytes .../prediction_kernel_lib_darwin_x86_64.so | Bin 262046 -> 268934 bytes apps/predbat/prediction_kernel_lib_i686.so | Bin 220696 -> 229004 bytes apps/predbat/prediction_kernel_lib_x86_64.so | Bin 248288 -> 257112 bytes apps/predbat/tests/test_kernel_parity.py | 33 ++++++++++++++++++ 8 files changed, 35 insertions(+) diff --git a/.cspell/custom-dictionary-workspace.txt b/.cspell/custom-dictionary-workspace.txt index 1f59c0f7f..ee6ebdf9c 100644 --- a/.cspell/custom-dictionary-workspace.txt +++ b/.cspell/custom-dictionary-workspace.txt @@ -447,6 +447,7 @@ slugifies slugify slugifying snakeviz +snprintf socb socketloop socs @@ -472,6 +473,7 @@ stdlib stepline Stromligning strptime +strtod Strømligning subclassing submessage diff --git a/apps/predbat/prediction_kernel_lib_aarch64.so b/apps/predbat/prediction_kernel_lib_aarch64.so index 2f989b60212c99a9838bc832ee51ce8fcb3a7dcf..8d654ad6f2569ce0fa3664fd2ad38ac27da7cddd 100755 GIT binary patch delta 91639 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 Bk68c! diff --git a/apps/predbat/prediction_kernel_lib_armv7l.so b/apps/predbat/prediction_kernel_lib_armv7l.so index eb1b953dc7a71b0cea1e1d985227c068c76a6660..2b2c3aa57886216e4055fca1436461daaa3bbbf4 100755 GIT binary patch delta 61272 zcmagH4}4SA{r`V*8z8h516J43iUB)UY1QC5Kb>?gXwfPa16J&?lN1V;Q6XZ{s>}q8 zP@vUfs#Yl)Ty-7t*}4y%%q|zovRvnIx{$B6gSD>=(`>T)3 z^PcxP_xydo&w1Z_&yBr*O6uO0TxUses)U^v&vP|YDVNM=!#1NC6VRI8<5ouNCmlHe7zb`#PoKN5d4f3y0DB`J`{S9*}17ZyLDy ztT3AwOCj-xO-u|(`1_N;9$s`-c;#8)^Y;73KBEp~=pV z4GJPxEW?|jR82<=s+9>oML2rQplrBM3amhZWgnj@a0|kf2-n2or>Kj;KA5GLfi&Pe zuo~BkiOKaZBJ4zqiy6*F!y5i-P|X_pUlQ~n!+qmgfUHy-GL#ldhQh9K;j56q@>Bw( zdc5>p1+Le7-qJ+K!Al=T`^4hxX^PE!dOQe*5)CfbQSlbC<~?@Y=`-bE9> z=XFe&3Zd|4$L!>ci86bo< zm5c*_QkhF|WaGFD$CWt#3r8M~AK;KRN^0`L(|b-<{OFda>d!x#;{R*sw{t$t4>~F) z{$sbR|J|Q;-@W)$wan4i`xeuw!iZC#h*^OzxTHd7pz$Lx2o3`PO`rE zLFFfpJ@?UFH_Vx5&AI#fOY#h=Z`ITE8Ztdh_Gwyxm?KkJ|{p8)*pSm)?Gi7*x zL(ko}{*QI7bNvL%4^Jfg;wIEsj+r>(f6&fYE2XvU+gQ}M@vpR6{xG_QwC^ zGGGBSaeM>QD@96)PDq!@-+UaG#?JJAt{rzSU4A{o(!JO5JRkfH隷}L9w-}y7 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 YxFmyx4L?($&rs}SG|~nWovK~_AB51}8UO$Q delta 54369 zcma&P4O~=Z`u~5<;Xwql(Z~o`8;y#Dj9e-Ua?!|02}eUiB^?kIjf{+pikeZ$$e_?+ zJFHKQM#dVyzHGYbmbp~anyFE-Eo)lC!>p__6A`s;67&CDb3PdB?tZ_2dL7^Qeccb| zez>mdzR%Ot{A_sZXJJ+5fU}+2#w(}TdTfd!N1!5qD*iL#JvJ3`RdJH@1+f~H`jfqpB1zJsTB-vjR!K33BHe zWWwJl#9u``?rBvylxW0DP+#%>pX<9A4YnLom3$TRFBMEeg(rrz_)EksI6(v(a3k2* z6rkk$<0F)GoFK9cJpko|*5sM>E3B#NrAoFp(ej+0B<<44M3mzyV$L|AorG4t4k?n?ggDj6qoDMgGKn4*p%n z0JKQCgkhO8nY#oW*Weh3WAG2{gJl?hP<{p4=Ks3^|6aRiWY`RK&$jSORLA%c7hU}D z%A!@vR~9c-9xh&0{9wN0rV+~=*04(){}^$lqhf?*&o!n$1?*W8agXXyM_+4NJmKL7 zC)}jmnQ_Kvi3@2Tgeloi|i!3$sV$gJWKYI%11_hfn*37 zPMU;b4G|PXl4dfNj3X1sBytj&LZ*^wWICBaW|7%s4rr4eTPesV3&=vUh%6>cNIO|Z zmXj4^6Otz3G z$WF4G>?8Zhz>ke74EGcE7ePS`8A~RRNn{F{MrM#%WDc267LvteDOpBV2*v)ZDcDNZ zlJ(?X@&MUH9wA%E6J#gZP42nu4zSTcc3B2&mTGK0(_bI5$MkSr!k z$uhFy2<^X`f~{mNSx@dI50Fjd5weABB~OqpvXks0yUCs-wEsQ|&XWD4a+LN?hL9#Q zf{Y|%NHZBr#*qnRBAH}kU=o=^rjlu725BL)$ZRr)w37K`0a-{Ek;SB~gn?4hPL`7u zWEELW){t9CCs|9@k@aK)xtH8;(54)qpou(09wD2_7P6H*LAuCJvWx5{d&oZWEU6rm zsfGOo`UBX4lHsI@j36V)7}89}l5u1LnMfv)DP$^{CKUTmryzs0kXd9lnL}F1e6oNn zB#X!rvXr!wWn?+%xBm(Xs>o`xhTKXz$y&0GtS9%9`^f`jBiTeAB99!S{Wnw4Lbj48 zNEg{jc9A_~A9c$WqcymXYOT1zAN_leQWLwvx4E9a&E{kbBAfmgY$6Yl zN62Qfg={rwQ(P2ul3ips*+ce`XUTq2Y33Z0A!ImdA|uEc((EVfFP4HhGJ#AalgLSA z3Yki#k?CXxX(6-89MVeW3&s8mC@3V0$YQdDEG6w^8CgzNkkw=jxs`O1wPYRWxBq$y z8pyrme)0g>NH&p&$Y!#IY$Z>SF0zyCBDCUZzDnNJpwg=7&~Y-6B=EG5gxaOtz4%k^Kgt|DSPg$q+J} zG?5WxBpE}R$yhRuOdu1L<>hMnO86L0ZTxGMmgHtzYH+Q~AZ z*nc?%6=W4zP1cZGNheuL){zb5UUENqfNUh2$U~st{*O@5Otz4%57|ea zCHqO`b51cCLWX}%`!`V#K}M1>q?wE(6Uam|iJU~Hkf~%EnNDVqmd|PbSrlZGIb=Rr zKo*ikWHDJnmXda|j4UTB$SShh#y}0}Bx}h!vYu=p_mca`17suFL>?lKkj-QZX*?6;T{iM>uIVMBMaMDCZk}(EtikX5~GLB3j6UiiU5}87#l4)c*nL%ce z*<=oB^%M4&PeB1$NEVUBWC>YH+Q~AqoU9_N$r^Gi=_G4~V*hm%)RPV5UUENqfNUh2 z$RlJk*+RCGCrB6BNp^vL`|qZphwLNIlKrIeXJd{-$Z*m`Mv#$Y3~44~$v86M&$RzU z3X;f4WD1!^rjr?@h0G$e$sE#3=92|vAzAci+J7+xC8V7!Bg@GOvWl!GYsjsnldL7{ z$a=DY+-qat0NF@3k%!15WHZ@9wvs1E7uiX6k=mgY!Zt7AEMw0*-W;Ot>g*PMRt+hWDnU#o+bN9epuGJ=dGW5`%Cj!YmE$s}?TnL?(LX=FN?@fX^^g@PtRSoYLi?|#U@Pe)YsosYo@^lZlKaU6WFy%`9wLvB&19>MffJ;Q>?FI$ zZnB5$BhQlkq|(YcCPT<@GJ=dGZ7~d($yhRuOdu1JVYKLo5>ckl{`VZ$WF40>?Zrjvo;3$N#!{0mkc4pNfQ}CMv^h4nT#dl z$V4)UoJ87E7)T}4$aFG;w2)b3Hkm_O$$YYqEFz1^60+2wO|er@MwXKmWEELW){t9C zCs{|9kC4q|3)xDZAYFdK z{yHh>BD={RvX4AVDknL&WC$5fn#c$;l8hnEWUNr^KaPR~GLcLoQ^-^@jZ7yqNDG-o zW|KLjmCPp#K)?MLQcy&ekfo%ZEF;Uw3bKlA>&W_(wEw*n>?aS9jbsyf zh&)0zlPzQ`d4hD2on#l;L-w7d{hy_vpH#l$9FrkrIB6my$Vf7VG?TGp0+~oAk&|o; zq>!m(8ktUJkQOqF%qDY4D_KAml0{@OSwh-M8L*ROWI0(uR*}_Y4Y`%9CF{s~vVq)7 z?k5izv?+}gG?9nMBV;q#Lbj4FvXks0yU8B1k338ElgigJ#jw9Xe*nuc8BUtW2r`B= zld)tRnLs9zN#rClg-j*Wgkt~c6l9PVGMmgHtz?FI$ZnB5$BhQlkq~f9( zli{R^jBweE43QMXkY+NLj3X1sL^6q-M5d6bWEz=HW{?&#%f>)9nL}F1e6oNnB#X!r zvXr!wWn?*7K~|B~q^*VlCs|9@k@aK)xtH8e9v~aZCh`z@glr~T$P)(f{GWnOvWx5{ zd&oZWEUDm27I}F!kPIQiNfQ}CMv^h4*-zMCECq370+~oAk(0Z+7wkuzzgKrpuKF1-AWcrQStl-2^n{&N(PuUO;s#l z#G|S*32&%dz!b3jF{5A&DDo4G$33np|1)ii-H9(MB%iWYRZ_wJb*hpETJSANI#{~i z$d^=M)RO~Bxk=C4@HGrFoOr>g*uK%IsK8-Vl%X315^D^3H7FJ`Mz9BL0-ayua~;s)Qk5fMM7ydqgH2!ynBSo)ts?JKl@lTd zU0{(LpADI?{+j=0oLK2HdRhcZfrP&s@ib5>sy=PVBfE`?4uDcomdD6f49W?*89xh3 zJ^fyz{vv#0BlR?VkFRe)%MbYK#svFI_)%5*ASgbkDrdp`0i!@9zPS;311R#GAWi89 zm0*0J0rf5cO<)&j2D680N+Re4MF;A^Nr?A>>0nBTreuQ=V>G1*JOUQm5GcJuQ%b;8 zv*w?Iq_IdqydM<#-f@~z3Kn09ior>-_>K>ZOw^QeuuK2KP_W zlp3(?7Ng#psfIl9c0+y$v~86PX`12$WA4DWL0}VD2Nq1zlzLFP)2JZ(ZbKfEY4k7- zl>99gL!L0($lnFZ2=swcPx(DYyc(4Jaal$@DNDok9|VbW3_%Jg4eDaN50oBM%rhEL zJ>SUZ1f|EtIY!(L%19I~G~%V8j8K-qf^x!~ z?S|a>k|D1LMP9zch*yJsh_}3K#9g4AFK(B_ZCmU~2uQ^_uNoN&K&hbUw?@1al%AB- z8}TwwdQ$!WjJOk&p>BBHh#vrDM3dey;;EpFob~rcybu(f>3$P&8-~!l&rq6XP!h8K zU=*12mQhjK0Tu+MqO5lex#e9$o&!pQS{d&Ir9sa3jP!a?8dUhc5w8ZNo|GoozbIex z2gZquKQuDfLDAyQKN<1ZLxvWY95&)kP_(%FVdB&d&`2kSs ziT%PjK?NxFJO5(H%UX?iJ$MNDlKx8jFZip`!g^2&><6WVHOGy3EhrUdeQCt)pfsfP zgdwkYu^cG!*mlE=ySt4BR(TA0lGn)J3QGN@wr`9Rn|q8FHGwkp1>YJ|647hSRXx}W zx#c@!Zu>wN;x&DSa;AK5D6I<=WiJ20(DDQSG_*hD92POi>%o37zaNVjKC`n${G=&? z2sDAx^JY*IB7H_Y7W5ZT0{rP!pi~s12KeR8frk79DDt#mBW?lv5U(3%#PdS}{ASlP z+=!b)1Eirgr7X-4RDoi4so_RE0~E817{LOd^tb^OdHTgh{w`1&-Uo`@G}4I2fRevp zlpznfg!O=;^!tAyaoB$s0%CU7D+2sx5n(nmT0xN~j-&iaRsf1TDb|SFL7B3KYYcgJ zoFPxU){vLQ8x7f;V2nuGgaH4D*MWZfKZ}42`Jw9rl!pH?*}HErDlq-hC{Ukd3~l|5 z#*jDOWaO{A*~nK9$|soz7*{6whgL}eWoi$BF<>j004CiMpd^Adpe-E%7XlezA7}v! zZw>zdjvKju4EYTI8f%S;BF&s2M-{<36y*;%5yS}d`0&J zD0?9<%)*DtVCft-^j_8vN`3kBY=)p>UVyR{8T02G3H$NodJW>~IfgvxJ{AN;UcS(f zw}MW@>lXzmwO~Ie9m%p9`3pdiS2KPVl>9BZhP=U+XJl*wC82t;kx-CtRMZK|5GE`! zcP)wTyJqw&RYo$v~bgb?2WHwf{S^Ijpo_uVhN4oWJ# z0p}B54*PGC06qpjBt(rzgz!PlLVO(DA{>W?2=VFk2_e2!b_wx0bf*xXH+KmqVo?&_ zj2)6N4oWQi1+I*QFr0qjwP<+|&y$3>xJ?n_IwDml`~NfvU<%TO_(VEG zh;OtlLVV<%CB(3E(>W`r1V_2ACkJu zCEReiq@IY9aA(v3gq<;+YW*UmY>Yh>S1=1hS{Er53nR;|O6|hPGOKc6VdPmQ00c&+|s$LYB@X~j1?#@)MA3%_~KhI?;PwU!$l?`5xwvcfHwVNMz_Cm6wy)R1B& z9pB`q-{{DkH(E^ zn4a^YR(6A9)P0k+v>P0=@5|F%iHi)Vl&tIl#yzPDI`^m#25JNY7^2M8g^p{ zE>%NKfmNy+VMh{Ep#kxZ-n?;|J>D^T@l9HKyd!h*(kR#X^XGj*`koMyuOy|yn8!Pg zEuNs&jCTwy9;20vcZ|uuI?D2|nZp&d&TL9o5)&Lxl}9;x7LD1nYl)^hYL`xMge)8D zNL`k;=f!3F1NW>h3{&^~^?`%IFV_@Dj51|h_xF&7%628y*%qi&xgWpC@kaTrwoer$ z)R|l5R_x9;RhipyR8ih)RcqWzk+VawIAJ@Mj=w0%hJzP7JFFX(Gm6RCaqxPiIh}1^ zzaVksbym99k6q&mRh(_XiO#n9$QKB?$ikHk?IN24SqNp3lvy?^wlm=r#!@%~8BLTW zQZ@~;2+C3@n*v!RW$BcqKo&z;7G*a>W~R(a*+j@<{W9AcS0RPhK^Vu3C6vWMmH=5W zdQwK&HIOAjR)zTC>({g|NpyCMfh-BKtwUs&LpF)^)v;^@WGR&G6`2h~b1{Ue6gDzr zC}c7XRlz|nMVZq9M;V%iJWrz`N0287vE-{wn267s4SXXWQ5b&W>+oij>Xn zF4uC=&cfkrQkGvPsJUKyduYv5vm|hv)b6EnD2F| z=0CfB@cG^vhI?y4%BL=@VY>s7U-I_(d{Kd^>)XwWv*UG)lu~7rN<_<_bq~joDWIw7 zS$8C;RF%0Kl$THt4YNM$j<7%m!;y-xmAN!fsd4`nm4tw}m)0Jll)K@_PY+rS8g@Fk z%BVloUw5U{+rA@QIg{hB_XXGQ7GpRrQjiH|wFL>o5Dr4-nC2PnJuke|HHjHtMLyNv zbLF(p=Q}-E=6RHSvHpd(Z1*5?9n{g@L$56sYvfyzcKY@F0QBcek6KyUz33 z*LSyH(ft0Ym>VkHa20K3<0{>1s6L z^q;1FRHge$5fr0xfNti)GFPv2&W<;5b;2yiK18#50Q8P;yC(|?<|f! z96dNPkiHCE)U2HGQBgK}^VxGRd7e?%xFQk9ed#vrl1?k8YE-ZmM-3Xb)*WJA+nzlRjk2z94@|`) z2YY$DT6Awac3z=M*cYDkus*Np$8WtbiTT+WiAdC|Dzn=#61OVOsV)_bF{A#&8`s!e znl`WFHndtYDV8a&JJfk?cWiXtFiw4>W5g!cm6D!>^k>ofm&LOrI@=B-9BLK~u674F zoo$+F_bF+dU7hX2iyF^iSXLQD_!qh zU)la5PLe2&mEyT<<1JF5Qiaw( z-FXd85aBQE>`*OtxbE0!cd6>Ujsu~}cqyz}Q(Xb7tK&muUfYLN&KpLlt2;0PV2wp1dYD~vLLgJ%tq)y?Wu@WNZXO--#832!54=^K>{sh?Zee_jKaMg zGL#y6FK#i|xmpVK()rI^WX%9)q?(KNmhE_{u!|g`T4k`Dx9V(KZm2^Pa(6f6x z9z&jC=!F{%m7$e+mnlhuERa15G`(`FZYR<<-r*XK28r|kqEdYA)9oebkm!h_%=hbo zbS@NmWWBa^q0)lcM(^_dtM%bsg($zU_ z>9fRCOFBl(7E_(mVL|%SXxLk*H&ybbI@|t)_%Lgks~QcoZ=B{*!ans3GdtVRP@BJ{ zO4x^<*U;Lh)iPHI)=Ft6lVt4`Huwo11spthsxlvKJF=At}TqUkA9MY-m*VL=}s=zO{pSIeiR=fjlwZK&Xq zVNT~rRC4K87y*RaBuyH39P#rOWWK{SHCGgEZpU}SX+b7K&)!w$w!Le0-e4Q0KGXq) zf}+jsIE75Xm@5rK8G;s0$B>H?5hW943xZs8!i08WIMp;)0Y*d=?KV*~40W*jv|q^v zEhq#dA=76;J%OkvWh$l(jf_A!T9NHv%m@x)d|;KmQ#4k3gnI(wGTX#8E2&fb3rE_H zHR#d&j)Q1yF;1YErucoryBL{wonkrYkW)G|zvB($2}Q#dbmlVYjMeCf=!tYHu*wFr z!HE?04p#_HD*Lg}A!ZZmH=B9q%|^iq#k^urSqRFB5=yTIEk`<_Jy+W;QzFyxD5m3I zEXk7Q`XE;P{`G%nwU3Z(}lG*`zIb#B{~TrnqON+eSmGOb4sWI9fvVbwUPk}CeY z%=H1}vf_z%^KT@d+u%t-CyrMrXV&{INw&uG&Rdd9hcw=UdQ#9hX{1ejy^MhLL|Qxp zEfxhF^wXkDz^#JqicSctu{k)SIGQXXuJ2<^-kVmGs6{9KsLzZJ%mTmqudCfGJtjEf8>pg>J^)Xuf-{qC$ z8m2VpJ49cu8StH!4XpSC@hjMxiEqHAvk{ji9S!n(Q&|IGsy6I+u{TGHWV@_kG$LUx z;t@Z@3FNX#98tw=xomQEgy8C@7U_SyxUyZg+8-cK#HMZTqZQ#Db?w{SM=COK*CNf8 z`mWqq%IPrU#*$)M(yo}DQuk@u3xs1IfZz8F6}P+=`)}+M&eoDLH zH>ZXv_q6q5Y3|RHYdqz2P~y6Fk$E5sP&T@L^!cV&WtX{PXF(UHJnh0=E7$k9)~iLu zvUCTHUB3@??Zfrp=`zT|tL*J&XO&wzWzl}qqi*9szR?+?0{fq*ncc( zZw>p}6W9nZ=#pJ5dxGtDC^nzC(-695Y=ujS{>)>IHZHsVfy*ux9Z<(^KNW!9V)L=P z2Y$of35s%S^ajkr{qkFXB-4;k>L|0PDMBfy?_3Svi9px(bHp{Z3lNu=)DF?8P&F; zcQ*0`UsTqsjc^XaE0RC=%tg2W;iU_XdR8v@+*3Q_Bd-bJVuW*( z`@B~ptSo5utiO0&`y_uO#9ow3=!L}r1l0i$2|K7V} zl(S7T-im>@hJEXeopIFDHsfJ$FyiZR;=r(8yvL=yj~mi1QP*!mGyBGco%HN{yV8?| zJSL^FcjIqH8?8YDUOoA$A$Z%p56Gm3LCnNuh&mHxQaNM=^ z3S01&D?ACKF!)Z{Da~&irpQ&%nsyoUkAs!adQ5mQEO9>05ISXpt6_(^x67ovBgX3P z4L7WD1;7!8j@@+X@hhHL8~BiH`|s_53=fKCcTB>hBCM*)DF2;Q({#maj$Q;;bJn{f ztkJ7P|HH9t+eNnd(I-95*T#C~T*|pmJ+--&?h_OK)VASJV2+k3s=jL+;-P0H(kTo)fK%x7>~CeTG87-4!-vxm`Co$Q=x5}pq$u^j@mXS z+_Z7d`jKla$`ha7rzi_M;uU3jHS*S@-1BH_%_!U=d;2qwoC8n5LU+Z(tk6bL9chP{ zThCZ)ugsbf{ew5(3`KW_eeB&Go$751d&g^vGI@K|yxx3NpqZRIQp{p?v)bfF>}FI} z_;!ys?_aKGg(vFrQed(e3!|Kj+bOz7rmQ$u5~)D=Aj z16YKcKq{UgRzP3A37ygxfJ($+$KkF79_h8IMarHr@F)k=gx>lomF{nLD}5V&w`S_^ky_uEm8P~t$PDSqnp;-Zm@ZIJYT)%kt zy52FLPUyY7?b_bL*BZPBZNHn)yYJg;df#3X-}}zS>v{wIy9LA92O&KD;~sBHJ9eh< z8JB;$ytnGyNzaM7H6w#f5~w(ELdeD0(t=F^1U$ln$8Uh&X_z0qy=_lm2KPNYCJ zBGHizs;qQ&k4xERgp;d0oe1Y9@AcX?jI_ICS(5pwd#}oUdsvV61QM0EH+pizdX9-t zwI(;QdDd;6nJ4Ae4_Ci(dPU2TLQ$N?z3WzI4=udIrnj zCe(i@fD;TYAU*11p@pbiDiMo7@27WDJ`eIZoU{fFmJ^pl!NhYbVV}WAS-sE3+r3kx zje1{1=i0-Hyt47gwZ%91O>}u!Pv%tKJGDY~hiEE>C;^owz&*&2O|pO(zUwAewnM{D zThBCjbKh?84ljDf6=He1Jp{WH)ikU9x3~*EEOjmByyd*x!0zO@G(;MoIHk%xEVaz_ zEZoQ?WoWU<(%7rSf9}~a!|GL%|Lpj3XSA)w(=@fp{Y^63iPdxY48xP`h;H&OUeI%F z3A~Gp(b%x3yknD}^rp`E-n-=3ZjOG!yZFn75t(5tUE8}}c9Kt!IOx~HE5g%Z)q)goAKB%tjeE^%|)6&*X4DhI5J=mt2$F{#b zQ4DEQ8+>e(3}QL-dvN1}C;0QlCBel^m%*2^gM%y$kcrt9Kh}HUIH$({-rtd7aI40| zqH$_LuWcn--!)NMcTb0e#dS!_B$E_MfX{D1`Y?;JBx-LbdsT}pee*klik!%PPe%fL z=q=EUR@MV`y(GZA2}>$EfCfoJbK?!Izy9`JrOP}l? zi}C2MEGQ;ZWAEUCg4ZxMiwp}%hce>_@6PCty*uNNc=OTs-N{qD`O%bGsMrw z!p{dl3&hWhzZXBR!fDyz^~B$&zgFq79sG7eZ{d~(?{@5jrasr;z5UAu?=sl${a6GZ zdRDFw4WGXX;ptfA#ODWL#xkGi@!p->;Jpj$Kze+GSJnaX_vx=~^IXyPV6PpUBk}j! z-v&3D{p-WcSQ}(rkY!d@NH`jsH(cH5j+}+15-k*i@GlArsxSx64&1`tESdeoh;`W< z_R+sA$%D)BdJOfNkx#qsz_8Yj+vbjWXp{R6s-xW4HI3Zlc82A7H;i24QqFDk5Nh(~V^PAEZ^u&D zgZf_nk6)=w| zR5$#UC|LpI(jdPNL>UQ-!HC8~kEY9o!{#qfdS0E8@7+D4$@{_M?VI~)^lt|a*wwi&LIsgUw3Y-_mk*{z2f+!F()v@ zacE2%8kK=%cW^hI{$-EX{^d5$wW@M_;R5Io9Otv~OT2kh;9H+K>A4DNGP(yavNEc- z;faGdS-CpBLj)-hq<;B5hTJeg8Q%XV-b#iy`3HEcsostYG(2>M4DZvf`_bt89S`ij z-c~?8&%k&UB==;#j0GbfP43t-);lE{cDBXne_--Iy^@xTG03AVZ*V-&)yr_7;UlQN z6}v#`IyQbV)`z`2&Rylj|J3EQOrW^ILTKaQzIr(}O!H-2lCVP*Zy?=*9fV#T_P$r* zA<&R+}+F?8`VG7P34;Ymc3;9C3x zEAD1z{83LDCPgM8ZvixGfzhKoaPqwWpfMR?)R=gyw;P+4+c}B5W{eZ{_oiX2Wi-+T z%VLxVSI#N6Fv9~_ISp1McFgF(6#T4qX{d1Vmfv}ApCO*Y(vct5GscR`WEqiK46kU= zbI>#ync`W--uoA-^41I3ZKbi^%P~EHZ~xP~bH=;g*KlLt<>Y+ao|x*jRb!Y3)lx3- zUXFh7y!tMWh8dT$sftTPAw_ zwj#O#?{YQDMt)k*E2AnlD-FdC(&oL3!y>(~LZR+@qR-zmF}P(CrvZxbbz!ZQIhK=4 zeyL3C=rPFqM~Z^Y>X-xl`4+nazb>J%a#C@5ekTrFf)5t|JVHiq#S@qI$tvN62N)xQ zH*mEGg>wAQ>zCP9cSsB~cuZ3K))h_b!W#0QoL4ALCu$|l5)~Vq3T206gNvAYK0{4n^ZEs9shdvL;}yv>ZnG*m2w1}m1q6t6H?fn*Fu1%v5B z8zmL`8wD?rhLPEEZk)Fmb(*T|y|}tQ{q{!#KKBJ)CN19R2t16jWfd3mY&5PKq79FV zed1y9rmsZ5>o-`LeQ}CR5oDAuOG-$B$aoCGJ>-gR8F0s9W>#&_@ z{-ENXLM?f)f;+KO!>V*_$Cj(SX|TBSrv9^q`1NEa(!@vx)5YQj&+?zUz#bSzWmwse z0rp;KNibFaIJKRF&Yi>NN4j#Z0Uuo`r-zOmx_9i^A!~I$^l6E7;5oB5J?shZCqvRu z=lnP*h%4Ih-Wy|VQr%#i;b)J_&UGv{iftd4dMgml{n)UH+>d)Qaq)LrcDWyYJjGl1 zr6GR+a=9|8!`4W4shZvHYS!dF9&R>4CtDb9)i%O{ESFp%#vk^*w+#8w9UI*Lw|@Tz zXYXHOO4EM9RZu5K)C=+t2)tkUzI zt+Ku0YU5_2+@=o3TfF|O%#|NE;G(e7^YPQho1AiOCo8SQGtT^c<52eHvYnP~wQR4y z=LMoPz#6vKn}OXN&G!8a+)WovdE)&6pY&KdAsvmzUC^~?%r~LdKHH#km!TY-YpBQu zxw-ommh$efhrQ0Q2XPn=6y&CNHFUrUyQz*oinj#+RlP93$3-8GaNaQup=MmL=3zSh z7pj=j9k~9>!@kCP1}lv`XpA~RZU^gh)w##`AwHhP8E z89fsXDaIX)o@3aF9V4>Y}uAGeD+bxntYD%WP)c*D}j}JO3lA`M8ya=Qnsb-H(UaKfk({ znJOD2xnfDc82TUPA)6icm@fZ`DDDcF9!3bjD+US zX!MMkanj}~G1=Xt5Q#yi3=ca~#9n1QBrzfh)navPv!*M;r6L4IIL*iR;=s0lUeI^daH8>>xB933< zxDxRfz_Fm5@CtAYj^`1M0V}{La6PCvjrR|fD!c@ZM%v_s1$o)|2`0)MOJXr(lHp0n zgPd@>9kYSf0mhj-q5UDt^F<(ZSga@bW7Nq%KkYhOs4^G)cq(!h! ztik?iix`LJX_z_n*<}LI*i}&Xn6}(x_b|1pa+)YZEUp3^5jlDzC4j^qm z(>m8Vj=dkHom}TQjat4y&Z;3fYml>=IX{s%^oOKXAg!Efht@eJH$`dhu5-+9in{eJ zwk#S)}rtqqNY570%A=EufUC=jCZ;o#n%v~ig&t{^y~h9QG?uB zHokDch@bhaZoroax&PZL3!Yg+7qcB79KO=_$5lox>%e8JMWe1`W3Bg2 z!A}lr6>A+En#XC5wT{=DqqNesj>F9_j$0ws72VmcTIRIl4V$RJx2yxD52#}4+C6JO z-5#JVU9)H0pMMP0uCY7D9FNix?T%ZIkJB!*I~E@IYG2y+WPTYHIOg_qzB6C_8k?&N zCigbTKm4_0<=2z7ZBIE~|N2&K^;3IJf4x-IEKfNG+OKw$v_)#MPdPTV-J}gX={O8{ zN*%9vjCMq}$7n^Rj+@%YXa%K?x$V2OwkJ_yvi6539g{n58t!-!##)4?IzDZScGPr4 zXlte5L@mfD^wSe4G~SWWS*kt$nyx_!rH%y` zkL*}^Wo6EJHVGiw^=~~k;N9H$UwDMt&mETMV(KZbD<~%dtb6CFlg*t4{ zd*4Kkw1FoJT??5NvWOwFCn0OW)kw?`SqWt6keP?b9)8R*=7;fG z!DEi;KSXJdJnC5b!xs}~AmcYb`S4D??{unC*^VocGhdV_XKuu}Snx|4=D%yoDU3n; zTIkm^juroyJv$6VGSq7KT)b^I*sfs6%#h6(B2yu&hD&#ve$LmAszV@)7$W;eiDSgs ztH*edq?mr~##8t6MiE0p*$jXp4Gp;THO@Y1)nX8B)(jddqq)iVzYn;Uv2NL{`F_-IPG-t?|)F=QneMU^*1#2 zaV>teJ|RFIqh%HAnE~p2EpfHJJ3zg9%$tuWXU5wGeAdzdp9w#PvJGs)kE5hOX6ezr z0qSwB=@I>Kpn8+`!Na;1q)yh%f894VNYym$sz>x`!_-V|!uzYSC8YNv|z z$sve;UaUVKg7`a-ho}d&%3^)jaKs-i)(3_oeK8sn3eGInw}+~`w5y8sX<KEGf2lcg) z>I!Y|{kk_&{VXVU<$&*mJ|#-MWMAv$YL2RXQ@HP@X!WpW+x#H>&e8#28Gcmfq;#b z8cuQv3V7xZ_#VgcYaD&|4fwtU+j0CJNA$e|zDyib<_-AD!B=tQ;aH7$7mnM}zyUBC zd5?hi%pLH3FgJ0)*NRNvArc7w9-NB|+j0hc&n_77Re;x`N54V?`p}d0Ir@Yv)a_c* z1NyNm)b*Nsr9RgT{X185_CNRUYrjhUOx1=zpuc$yOyP$6_2bv5 ztB1E28WoP#ccg2V=|ypB+ISCS8^1LiLj)Yd`?w$|fvf=oZ+;uU{WE*O_sE<9-_{TH zuj0_ScMA2T*Q!rxPZsKbyA}$#YlR*>9wt#)s81UY?U-1okBV2n(tf;O?~PX%jtWLy zyL)_RdfwNRzurCI%YR?bOMof$+^=s=K>0)W>u)8fS8Lxa*V_}+iGhE<9~UvHx2O?% z(I3@VZRh>^g!$@Zz3MtdEbr-WUI$ZNalbxsf;v^3cfY=Rf;vqrS*{>$lyaCaZTD;=o@*Tmo^DA&xf02Oti1O&{=; z?$#&YqTZ@`mg@sIsF`|k5)!uF1+Vg3BjJzB^{SqUWt9G~z^K-A3o<6&G2n}P#Ym`O!XZiMPlFBB`V)q) zC@`iyQeSh6dYNvyRm}=cMf(1ije@taU{W#))=q_5zpUpaW8C5j^tY0snO`r{7pADs zYi}>py(yTh_9go0+tdlcA1zbPB)zOpzfE1OOg-wJ3e-uhg92800OOst^21eN$`8 z*WXM<#^g>2`JdMWK?0wI>jHN9!Yhi($=5Q`4p1?P=2!4i?Sw7U$Z z-$~OSwnRU8CoKB<#rna!)M)*uJJp$5NB+Ldba;}eH_;1el^JIki&77;R8_vd`7V^& zpC_fpYo+=6X^Ge7=_97AA8J$b^)IHYt4H67@@KkyXVy>oz}>PKx13(ZPkFs;sNslw zQN!ta_Y5^g%XoQTXofmY)m~e?Z^GT`c2&E5v3@L5-K?c7)>q7gSw}3^H_XH-QgZdz zXQ~rNj6-$ugL>gO(&KdROmz0+JpFZxx*=GL8}RjP+BbQY_^gR}`lx%b62|4}Z{33m ze7X8p_n^W!t3Gg#Ix%=e9=_80&Aywm)OJ-X%GIOhVtKqVR}a2dZNDle*BAi#{$I8P zB^-bstcDy<>_S8I+$QxhZOkJ5>TLM4kFEP&&&J@5+KD{n4oxZ0H6;m0nm$B{?zf5( zI?HQT;)0XQ+Y702@Cg)TZ|IgTleX!mZ;Bym-8{ zVBff<>S$GqyHCG$8D@0sefk&6(CD@teQp724qc$HF2DqRlB17V4*3f?`u63J@1L(9 zTn>|ZF-O-{pe0#3`i2#dKRI9Dy#fnD1mgE&9SqOW#}}%bv_CD-4;EsAznQnMy-*!c zwH&+Nz7pCPJx|~LARL}LZ{MgQ*7=8n@iNk19Dbq`V(>Rf@2?1uhE>@`uxYRWVK?gcns%Vnf>qQEqEN~O<%rm_v7k^ z0mJ9tYvkzBcf5-|Tg6lAAyxZl*1oxR>URqnT&S)XYj; z6GZ>`lkeO=fAW3({ZGEyAAa(!$MFG( zb2O!Kp}u+p)ad#weav&}+TkOzjONeNKV7R{q91rpE!Ixoqfe|*{}$S_0DF-f{4C%C zW5Igq9(`dYDlS>D?^vZ8tZGy4(Z6^eQ8Nk~O#KHP zN`K6v@2pW@3_W7Oz1DR6IP9z;?n$@kPyGh&sWx+n@Ii|{W;2927Gu=zwCD#nt80U< z>io&qrBB(WCTpWD#_p#YyY=>MFs7&P*00`e@?Ck}GHG znJ=mB+UZPvqEmfQYs%CQJF&%ZX6~E6L%kK_pQ*pN6BSI#)PLNmzNHP%)ZctrT{$M= z#7{oU-S{2iyYRD<)A4J)2ur(;%zz2rX&C9B?>5^0vytYHu1NX$zDy)n^A&gN<6eO) z`t9BNo3B6_p1E6}ybHU7ff@SJUD$d(aJRl|m%0I~-qF|8D|J_cI$Xc+RrPjl!rl7m zv+6kA{(Ci0KlCbgI#=DTfAK2%aV|q&SqJ_(LmzRUHX-n61{Q>$eN0V;{(QC;sc)}U zL-nn{RdYtS-u!dB26q|Pqp<9y)@0~&ccVRLr|VDcR>zMnLS+{&4FMVY!QJXYZDxkC zllgG^zwczyhLkh0?|+%0ul)at`}VM?s`dZ9-x&}P3=u~hak!`mh=_=Yh@gmwh=gWl z9#d4j5dtE|%!olFk69U-`Fe~zilyUU)zj6R6LAZ#lpg2Zm8#y zE%GRuIE)W(K~Ek$jFaEPjI+luUj3fDg>*=v3jRN*^4=;;?@pxhr7CpOk5V~ztGvYU zCTgilLakAFDtm21uI5x8zYV!gPvu?Pkn8YN4tif6>k%z5=w-^BZRxKt2X*twlefPw z#~A!H3941zHk4^QmJ4YA(c59Fjtu2n+aZFFhw}Ijq4+&|s_^M(@BtI@S(Pw80~}v|5g#u0wfmwH$8nyH5(+QbZF4aqvz#j6^CsVad;? z@U2?Rug~t3qYQ^q9QmrHo|eMlA3_W}Q+VEoP@Wz`c+H3Cfp4Yoxep8~y9s-0pAO+k zdtfG}4dM8`sO{P=8k^E@2w&QZ8pLQlTMrSYFPZB`$xR3N4<+c9eHxM>~N zP9uvWNnE^No}}Au(i-h8fQSk>jJ7{#eJO_-QcMmjqbkbKBwqI=)O%$T-}n-i)||xS z51=`(B`VEXegMsxmBa@QAP`j#{|Z_alf?7BLe&G3`0!VVyb>$5uTZ11L^jnT+%m}4 z$dPIz&rZCzk$)TH&?&J&EjD^f2l1|2Xz7tbLcL=nhuU%41=$zC&Dwa=Itp}m=N~hu zI{Ry}o6>F&uRaLJB>wP_+%@utfg=Bv4N5wT8hpgdyk6aNel*hRRC#YY=M$?#|0`qf zaay7+9om-2yAH`gatNO~gk{6JME>?0dAwochI_FAiPg#9V%VU!1}fO|18rE}2?Opd zg!)FYdK8Z9zmZ27etgG~oV#5lPhvbZQLM)n#8T~651v?w8N$Br<+-$IAjclYG`M&m z7aW$ak?%mxK7uLZUjz8k5$yOK9KdUiVkp`_fMb7}SZI%@&TuB$l{X#f9fOw7iRaIcVV>S*05ADbUSj$qLAv-PHgj78_dyL-kF#p9 zk1btTIHIPZJb`2DKgY;K1XMKuH3RJq~LzIe`xzmxEl7^;eY6iBDaSd(f~14nKi5 zO-$fPC**WjHxxn$q92bCv+%kT@?4|d?k7qAu=QARlr1)skH>R*8!}Og{=DEMwmdGy zOBd^%G#znQykdW1PRYK8{Z985a!fpDpF)p$2Vy&g9!&&z3i=$sr(f5h>vbC`1s z?$1k{Fh*zoERUnENb+Yn-K!nqiqYVmIO$@=KW|z${F6=Rp=y`nc+Givp|KABr7Q1M z;Yo3v_zUX#ejG3P1zTbp;`qQXs77QQ(*<1rBaY)Q$ORtRz^f|WiF;m^JJ6|EPQQw% zBjecXB05!a9FM#RYt=oD*ImTwuuUAdY6SFJKL_+R?)g4?M@6Gt;&D*pKaB%kAYUH( zE2g|3^y7uU%Gn;PG~vC(4vruDUcxA~pdXLCBo_xxMYyQ)m00QG_2u_g?OLp@chaza z9DW(|{qFsE-DT)$fJpbQ<@@$nzHwPj_HfqZIhQBykYA${v3$G<#;W2^%q7x(!wCF- zEHC*D`cfXt7k-nYeIDt1uLXS-h0<)2j*V5O@m0UeoeeSgI*3{TwWD0`%NKr!yobkf z&>s+9FXZuu928m^WA7-MZLeUYt>V=Y|D(Qq{15CRv_wW%sXnYN0W_?JulNoMSlA zf?dg@eZ&@LD0jXoXUKaLOok1EmFG?DQ@_)PKfejU{60MT7PdT|?8Db?LF@@O;5=*@ z*z&24=1W!t{}KJh5*jc6$Rk=%C-#&v1OG1C(Fp2zJvEwJ?Le`1M)N$GR?*UEHV}=c zXQO!z(JIb&C3haz0;`LY)v~)GRg;7|C;h26kJeEvMIxz2Od=y*0A#0*GRQlc-So7D z&iCeBdL&xcn~hFXK=1b!=3oWA+MA1AD3mjtNpF0yH(tg1+`WCGU2o2HM)Enmxzd@| zQKAhLZj43z+IjcJuZ>dT2iW3=u5h6u`ZG#o6mGm6h4%gc|m> zRN%1-@l;i;V%w~KpBrplxhr;u-;UzLu9QnJMsczmji$UP9J8TzPXO#jJ18Uyk`Lsg zEh&y#N4;?g6&&DBdV{M-)ZU3Z+lS-wUOd*F=6Ia$<;ZZIG8{L#(_Gr!i{m@NaF%*d z4z23Nzk5IuFZbf`Rw(WBy?AOXh%>VnAH%ilcRlT$nn%1yJt(P{Fx_HK?#}s-kh`%T zGTAiSQF~RJzmDV;k5D`X^y0&h&>YhB;&e}1M#m#XF9>D#*5qRPJ`#Javu;}JjySr5 zY6+%Ba%5`?qH&Qz^w=VAO`U0Lq_SsU)tWMCMI?K9Q8qmj$;Dof)r3es?nQxt(MVMY zx|29ejP* zZ#xQ?>7xi7Q_?PaC4wv4Q?~1@2&H%vcx!u{ZABR=jAn-OBqK%Ah=}SHMl#5uANPpIXXzkD}udzDcPVGIouVI5z!az+}MLF zeQAO5zsTT~tb5ySqCLTJ9g*OU9=xCY)rLb9?YS6BK1akLpV% z!Y10;a8C6{i`Re6i~VU;P}mbUt(QjKv~C%F)4CC~2-kO)DifFhl$&V=Z$p zH{P>e-2R@-C;G_!$-kR&O1`5I2{b<|N6?4D4ibLx~-^}mD)(elkDA$%i>g7n$KdwK)rrz1m@e!8+Z`O}6F-qjo0^-_qVHI4I;V%)HMwYE(N z7e}LuOb@wj`t*D>n#R%a5RQKe13_jV=-AO<&h7*I+73171EE`kMFDrnN%TuF?}(vn zkAv`0)%^z^;YI7?nej6 zE113FXkp-$uF}PlWLWOOH?7_vRg+bvD(z|$xW@s+Q!|ZK#-NP;P|PZX-|in>gOvWU zva8ZRyyMA-Uc*H^Z0_S-**O7f+18#?7`8lI__q+b4aIlibqSPAe+BWS1X@Bzf~t!L z5XrP7h!+f`PiaaJCnsV}w4^gnO+?iag2a)+RO$l%L3GRL8YErZTxq@7qt{LANqhyc z93MXL+>DR#ZRYVw^gHe9#3Kh&B|X!HZwZ5iuJvMP-U_Guyb@4i3*d}Y((C6gS5YICz{hQY zE)r0+_%foBVpkc9b!-V(0U~Oni~37pi<~t{%p#iczym7HKfiS@}0j@onqi>UR6Wiv4?I@ zLb+-L>17|@nuAr-J9-?WJR7K#*PtAuc#otsDyrc0F&JuX#|7#32-=;evm-GEyHwyj zm(J1k0KV}UdeV0Rykr#m$HxKH$4Ajr*=^BFva|_WlJpj*kEVmvBY;g$(40qdI^MKS z_P=R;2~<_C6^+%Ok3WH~6;&<@5KpKRHr0!DyWh0M>Pu_=#VrzvjF0X`wIJh7D?V;1 zMBA6OT7zBOO`($7>iMPh`-n>Euc_;+wQ(0 z&>v#4PYG0`_<^6zvUs?OFbo{R;K%dZt*IlA9Y@I?m;4<5fnvhy$F<`y2z}>gOOw9x z6ZR*PM*DHWQy4(j`-!<>r0Z(nG^5xeKaL%bY1&LbUN;^^%J5_31R)eZUOWMv(%{FK z%oTfFGdZ#w%B}lRFOPE?uf9B@9}Qvei4;XOCQhA5xu#7B*9Tyq4U$)Dr&^%?CS|Ot z$irCkf{D{7!IWpi^S0SJ<*S&TktW6LgiR(N!%&f>T~O*wz8(UZj0tt1rZ~No#pM4c zQ$G(^jlZw5NG$Q?@mVyM8awi?ELft)I*Q$mu~gBKk4+KtgN~d!6_uabkw2YE$!=ph z;g3 z-Pi73kss>7^PWZ}1AJ{KJU%OpcTO9`lmVX+(o9Kyd@_%`Z97WFXFA~1240Thsnv7splHPP zTy&I-4s6VWY475I`{;dvq2@Hy>yf#6x~`GDXf(Ynuo4`|P01rKk}YXtXg z&ljG-s?WJSC(flC^o0+{KMQr;;=^m6CESML!-4ZKZWa3Q;(5sVQ6DxvN3s4%KGMZW z(oO3PtL3)-tF`^U9p)ajzrZ+_J%=etM;|`-9ITnE4@Vc#Dv#6c9E#<^-{fI2ezk}? z(V=#1d>*E%q8*QYp62P}=AiDovnYlAu`x%%?QZYVmC^Wie7cy@JyJDk^$`7{1CKFd zZP}%r&;vA$83H%9V=AFF^s9l_m0*!_!r)L>wa*q9l=GU;44gh6YrojGimGok@Rs>d z#McdMT0kSoVBmrUNNa?F4KL7M3NY~D7a+fuz?VXSo7(WaQgo3EZFyTMa0lCpMURo2 zo+fu1?9Hh!Qnbg8whjsC`L|w}!dJXVdY7&6|Ln5G%1u_>+qdsUs-k&qmD|4dl|W2u z7gCsMY#V^FKCwObhSwi_j0XyYdS?Rs^sjtrA=aZOygB_Jw2cgHnHHgx=e+sTMdtz8$P%g+bwb4oc%HxsjW9Je3=5NzZX}&Obh688xDVk41un|xL`9$ zk6W>AHxy>fZ_p2zkNokf6O?Ib8=m?K#fSe-)Da&+aq)lov{*ljZzx>1)q90_EBF}^ zejfDF?-pxeHh&9@F}IE50Ro(3<53mm)MR=a4ts9^fQo>fz1TT(%9rLv(ym|jW zI~3GvK})n$W(D3(Uvk>pgN^GTR2O&LB0vV`wjS7S%;2%>kjNxWyesZXyz?!2FXF{r zb;qGchQr=I3!E5v@Bo2}-uA%JYbUQt(#0L$I&6(N51Z`)J5#@od`$U3=u2KbElMJl z;iYP*o>;@n-73z^^kA>`6y$XVxrm2^gjl4qg$+S1Idwhe5L?{2cs*LaS4&>Ko(#rO znp|!_IEAMC`5QjC9=iRyJ6~82%Q@~SM{a;wtCD!Z28;@COT2dj!t>nu*ak{;8;|@R z2W21Tpm!mab#9#cF5-o`^Fnd$-;yiAF_-=NUFtyHknFpFcXnszN+j>)&gqq8igZH~ zGALr0LqMYPWo3>>170n&;u}6WlcD6E_4>E$i?#ukc}b=>nk>Y-nc$6}P5T<5+=&sVp7pI&e_r2&U;A~vLh z2Y{x3WwA!pSgbuhu~;Jp@s1DahRN9;#|8XHS8RJ8uvlY0wpiQkvsir+s}JrXH}Wq+ zfJmqqd;}#hwB92yWO%gS-a78H~avps=rteEMJHDXLO|RSIydlCtr6}*B_bt|^L1|IEYCjz|jkd=b1Ktf( z_L0T9XPd=33^b+}FZq)8n*8i>0>H1pLTpDl>$X~~d7z@m>g)r!VUfOc!ihFovm1NV zLTAnIacC_};L7TkYN;RmffMrAfggs|$ikDjMWDDH7HiinXsjxWRgdfCpfT_p1i#Un zs&5>mL|60M?^&#`thHEoueVrlZM0YeHd(AE!5;zN4c--e4fy{mQ83Uma2J7wfv(~D zBEt8=Js<8AxM#s#4?2PC9pJx$ir&R|fv`59WL$3r)xjOI$zryaA>w}#Arc-_;EvgB zv33K+;(8(?E{ESKxRXFX!@U4B5%ERg`XSzYP!jwE_8Q{+0lpBl8SX2HcNydcDu>@= zpu?ayK+_Q(Qki72UWel&L|6=RLZX=nJOau_!b=g>2={N`a}j<9dEhlimXO*WhVtL8`$KHY^XLl>TJ*2I<^u zr(0iGa=OOCrjxkua_%Xd6_};Z;d|hf)3rBtHypxGz20}%_4d22H{5kye%E!G{krNf zN`s&0mwM?s+?{b05F?HQ@Y8>ZZ-xrbe0Y?CitxC4O*X!d2>uPY015X6xGnp!&yQac z{K^s6r2skLB_I`>gS+rW0mQG&jx|51^imJZ zsX!`tr3PFJaN!W#MGDGE!Mzh8ZOx;G;&x}yN|31e7k2E#bPC)yRgxw?Mu9PcPb9Oi z-wZgiBz;@Kb1|6~ywKfgI@)jIGj7t06Ts)W>&5lt$t|fHt|#ZTpc~V{XHw_og6B#4 zlXz3nXf!)y*xDXj-O>}lzH3b~_$AHh8BI(};E-T0EtZ$tK$85dJ zm%^h^Pa_4NLxCyaQy!(jL?kc;>!&$LV9G4=&cgMyDdaU=@IvyE!Dr0X(Q63LLCxmj zItSr-g3qQ_KM9U_-+|8@N`XrSPou!~f}3ZMyBQhH%po^XqM0*gdI>ytqLWhz63m@K z-un?TcbcRZ@p20#eH0{=`;3#`7d6QnNrBxFo|i|a3y?rw0U57?=Ocr1_~+-4`)c6w zXX;(|2#)*MHwZpk(hGlcexY6$h={ZP?&|+1GAtNQfqQUWfSQaE93qQGMg=p;Efg6S zphhj>KO6o-;6Hmdc^bqunrs%DXf~Qk@WLtXv{djJ?mEG3zpw96cJm#IQ-)_U)`C=} z)8{%gHtt^V9oV8bNGb!V*j^g!+y`Ru)icpo!&Z<;Wf_xH!=pP8E@5K$25a2UyJ4fsn`Y^7WQBK zmNx@FxenG2q=H-LJET?D4A%Ptm~fDa9i+j!o9iB4W@`#}4@5?@BF0;w4v(}4FilkxUFP)v}D^_u07mgP>Y`JQ3(&_0sRgH&*;1|0Lv z!=+XBCF}=C#TIF>h4;mx|EuHm(OQTLq=Kt7;HvwA9oUrrk~9u<5+p{v%NlIs!?0#y zeCl9)K<7aM98%yAS1|Sk9yZB{`UXQS$mLrFo2$WQHG|Co#$1BGitiNgMh&>48F1Ah z+&2kI`(DBRqQTZTgUtt~6a-0|Z8h#R+fiem?;c*`%wr@Kg4AYuLW3RE40bx6rY{1i z*oCvrj*QEi0gpM3*$zkr@6cpi+YC1C1WB176?kh2>zEkIl zMm+8fQo(05;Hd8(F0GnNBpn5**e-u}NGtyyEc(B8=30*zpfrJ0@RJ(wrhCA5VqN~g z%LhOz_Ein`{DZLO5M>e(bp`zxq=G-wfIDNA|FCA-|0fn9AQgK>gUxIPYu5h-D+W@* zL3149DsKi{VL>y2RP1;S_GmNM{lL{*(En9%nFj2Ao51&hRPbU=#seOJb$3^=JHcx~D)v)g(|{3UjroQqA>nyHMT=>rB$NYQ0ul*{ z-_8fbulH2qUk7(@?Z`M5PeH4O>xzOkKXCb+>7|njL29XIXuuIa+`ph|8*lf9s6i_B z-x_Sr9a!{#b=`ibty1bHaJ|6+KBNI}xC89KHX^=QN4T`pNxmR8V<)^qTdncg`(Z`@ z_xDl2ao`ys6&$Yt`yYFFjgvY+t3fJurUp9>*c4yr4=AFePO1Q@M$art-3SlKq?1O0 zgi@^1fLAt?@djXagVc;`HP}NBz;5tUDqQ2IGfPKtp@MH}z@9%oyvEc0by5*X#YWF_ zh&rtqY#DHCZCJFwsBxYKyr>y)6M*^vN5-2q*qUarjlfBP4(xHW1}xRATQd8> zRmD`b`Y8MwK~0^MW->nKsBs*y_v^YUHaJ)(#er05J!;2_`G+*O8L*VBle|GHxJZ-n z_GYkILv+$ykc!=`!8X-n|8HN4QsX-CyK8(Bepf(+LzNnz(}2T%dU%bKhNDM-)QsB| zIixlHHWuyQ2yx$?@&0ra3Z#OEYQSp&j>~}ZfwqJ0#x}xF8iBX^jZ_M4)?iQG&e)!> z8JVknQFO(f0M&xjj5lh)zQ-S4u;=p*aV>uU zSjC9n#v@Ori60fCJeI zZHDm~paEL|u9*4Yj87u$3Mg!rlJRpIYz)%MhYr<4r|wti-3Y4#`TSkMZUojWMyG6S zm7brh&=~MkP(P5cjMovV4qUj~!&;037r*J?qvoO)fU-dOpiQ8)C72@=!@fVKv&E~i z$6J0^yhV_FeG%+`T#-_men?y-Dz?WnZDvW5f^lzu(n|D*6*?*Bb&QU1XMw6frMMP9 zPs9mBcpOOG`xhT36K4XV(4}xkA&zjr3AZoYB9FbcJZyiGl(`8RfaZdh3%*$=joSha z%6Jdru0p0DX)7`TWq}$&uWZ9`3KGWFk2vzF$C35~bZ_X)2q|qw?$c8WV*S(7l2osO z3Dv$3)NCy(8bA@BBz1us$A@`B14K*O zNa7$_XL1uQD(I-p>Ec?nyr9!AJO|g#LbW!v=2fyT&}~yZ+@O6P{5is0g;oj5=U-)= zpIiNKNfIQr#UN*tdE`V%*n;@bHrH1nvLClQirGUM)NT-PP>5)rnq29wDeyv$G+ z=&H0a3d=u{&d<4SKbn0%lTH^1w_dnIh5HcPhxYSGxLr%p14~a~j>FIE07-*-r=8|C zB1owE%G20c;;#|pHV*f!jyr=Xnmb?9A>&LaUgjA#;>f~vF5GhwHk1eJb)B4qGni+> XNfl>!nO+yC5{%Y-f=ksYT=Y**rRu9IU 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≠m_h$yeslCyYx?Y~SnUmkdJ= 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 diff --git a/apps/predbat/prediction_kernel_lib_darwin_x86_64.so b/apps/predbat/prediction_kernel_lib_darwin_x86_64.so index feb706535a7ed41248d198deac06a883b505aebe..2952311a6ad44107d23cc9bcffa7e53feeed77c7 100755 GIT binary patch delta 74908 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 delta 68187 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 Bq{RRL diff --git a/apps/predbat/prediction_kernel_lib_i686.so b/apps/predbat/prediction_kernel_lib_i686.so index f42ccbdefe4cb266a537450315b257fdd73110fc..f6a7582a750070ed1fcceef5369a5874839f6d99 100755 GIT binary patch delta 87531 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 delta 80058 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 diff --git a/apps/predbat/prediction_kernel_lib_x86_64.so b/apps/predbat/prediction_kernel_lib_x86_64.so index 9eca7a3690db5d2838854b4e53d9ad7bc89a6e5a..216c2ab7f21fecfccc80ef789dae352e824b6553 100755 GIT binary patch delta 100098 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 Date: Sat, 15 Aug 2026 18:25:05 +0100 Subject: [PATCH 04/24] fix(kernel): do not clamp the batch SoC range when no range was asked for pk_run_one clamped soc_range_min/max whenever the out pointers were non-null, but the batch path always passes them. A job that asks for no range (all_n, where Python skips the scan) would therefore have come back with (soc_max, soc_max) where thread_run_prediction_charge_min_max returns (soc_max, 0) - Python's clamping lines sit inside the `if not all_n` branch, so they never run for that case either. Latent rather than live: nothing calls pk_run_batch from Python yet. Fixed before wiring it up, since it would have surfaced as a plan difference confined to all_n charge windows and been thoroughly unpleasant to track down. pk_run is unaffected - it passes nullptr for both. Full suite green including the slow tests (debug_cases, annual_integration, load_ml), 101.22s. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction_kernel.cpp | 21 ++++++++++++------ apps/predbat/prediction_kernel_lib_aarch64.so | Bin 247200 -> 247216 bytes apps/predbat/prediction_kernel_lib_armv7l.so | Bin 197840 -> 197728 bytes .../prediction_kernel_lib_darwin_arm64.so | Bin 304200 -> 304200 bytes .../prediction_kernel_lib_darwin_x86_64.so | Bin 268934 -> 268934 bytes apps/predbat/prediction_kernel_lib_i686.so | Bin 229004 -> 228908 bytes apps/predbat/prediction_kernel_lib_x86_64.so | Bin 257112 -> 257112 bytes 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/apps/predbat/prediction_kernel.cpp b/apps/predbat/prediction_kernel.cpp index 18d8840a5..79bc6c776 100644 --- a/apps/predbat/prediction_kernel.cpp +++ b/apps/predbat/prediction_kernel.cpp @@ -1250,13 +1250,20 @@ static int32_t pk_run_one(const ContextStore *store, const PkScenario *s, PkResu out->iboost_running_solar = iboost_running_solar; out->iboost_running_full = iboost_running_full; if (soc_range_min_out) { - // Mirrors the two clamping lines that follow the scan in - // thread_run_prediction_charge_min_max, so an empty range collapses to a single value - // rather than leaving min above max - const double clamped_max = soc_range_max > soc_range_min ? soc_range_max : soc_range_min; - const double clamped_min = soc_range_min < clamped_max ? soc_range_min : clamped_max; - *soc_range_min_out = clamped_min; - *soc_range_max_out = clamped_max; + if (want_soc_range) { + // Mirrors the two clamping lines that follow the scan in + // thread_run_prediction_charge_min_max, so an empty range collapses to a single value + // rather than leaving min above max + const double clamped_max = soc_range_max > soc_range_min ? soc_range_max : soc_range_min; + const double clamped_min = soc_range_min < clamped_max ? soc_range_min : clamped_max; + *soc_range_min_out = clamped_min; + *soc_range_max_out = clamped_max; + } else { + // No range asked for. Python's all_n path skips the scan AND the clamping, returning + // (soc_max, 0) untouched, so clamping here would hand back (soc_max, soc_max) instead. + *soc_range_min_out = c->soc_max; + *soc_range_max_out = 0.0; + } } return 0; } diff --git a/apps/predbat/prediction_kernel_lib_aarch64.so b/apps/predbat/prediction_kernel_lib_aarch64.so index 8d654ad6f2569ce0fa3664fd2ad38ac27da7cddd..90e1fd8ed70e4aa093223ffebb0e00edd529de70 100755 GIT binary patch delta 63858 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

YeZA)%s-C!yLHPeQdb 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

Kl9ih38HrSsa3XmVuw*{ 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 delta 31860 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 diff --git a/apps/predbat/prediction_kernel_lib_x86_64.so b/apps/predbat/prediction_kernel_lib_x86_64.so index 216c2ab7f21fecfccc80ef789dae352e824b6553..609e1471e3da306f77b0cbe0504d525dc6c5bb1e 100755 GIT binary patch delta 9550 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 delta 9533 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 X9~Vi;^^MPOV)#w?!}FUG-*o>!6F%f& From 81ceaef303faf13ff4d8c20214504da3d611ac40 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 18:30:55 +0100 Subject: [PATCH 05/24] docs: hand-off notes for the Python batching refactor Working notes so Phase B can be picked up cold: what the kernel work already landed and what it measured, why Python is now 78% of plan time, the lazy-batch design, the traps that cost time here (the export window mutation, round_py's locale contention, test-fixture isolation), the verification protocol, and the three approaches already measured and rejected so they are not tried again. Delete before this branch merges. Co-Authored-By: Claude Opus 5 (1M context) --- PHASE_B_BATCH_REFACTOR.md | 224 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 PHASE_B_BATCH_REFACTOR.md diff --git a/PHASE_B_BATCH_REFACTOR.md b/PHASE_B_BATCH_REFACTOR.md new file mode 100644 index 000000000..35dd7dfb6 --- /dev/null +++ b/PHASE_B_BATCH_REFACTOR.md @@ -0,0 +1,224 @@ +# Phase B: batch the prediction fan-out from Python + +Working notes for picking this up in a fresh session. Delete this file before the branch merges. + +Branch: `perf/kernel-batch-abi` (4 commits, unpushed, based on `main`). + +## Where things stand + +The C++ side is done, verified and committed. The Python side has not been touched yet — it still +issues one `pk_run` call per scenario. + +| commit | what | +|---|---| +| `a3254924` | `pk_run_batch` ABI added; stop filling the SoC series when the caller discards it | +| `2e71022e` | precomputed SoC percent buckets replace `round_py` in the hot loop | +| `be2510d0` | bucket table verification test; all 6 shipped binaries rebuilt | +| `f813d219` | fix: don't clamp the batch SoC range when none was requested | + +Everything is byte-identical to before: all 20 random scenarios unchanged on metric, cost and all +three PV futures, `kernel_parity` green, full suite green including slow tests (101.22s). + +### What the kernel work bought + +Measured on `cases/random_scenarios.yaml` scenario 0 (the benchmark scenario), `threads=0`: + +``` +calculate_plan 2418.4 ms -> 1758.5 ms -27% + C++ pk_run 1056.5 ms -> 380.5 ms + Python 1361.9 ms -> 1378.0 ms unchanged, as expected +C++ share 43.7% -> 21.6% +``` + +20-scenario benchmark: **42.5s -> 31.6s**. + +## Why Phase B is now the whole game + +**Python is 78.4% of plan time.** The kernel is no longer the bottleneck by a wide margin — per +prediction it is roughly 20us of C++ against ~70us of Python. Every further optimisation has to come +off the Python side, and batching is the mechanism. + +There is a second, independent reason: `pk_run_batch` already takes an `n_threads` argument and +scales properly now (**6.7x at 16 threads, bit-identical at every thread count**), but nothing can +use it until Python submits work in batches. One `pk_run` call per scenario cannot be parallelised — +that was measured and rejected twice, see "Dead ends" below. + +## The design + +### The call sites are already batch-shaped + +This is the key enabler and the reason this refactor is tractable. Every fan-out in `plan.py` was +written for the process pool, so it already reads launch-all-then-collect-all: + +```python +for try_soc in try_socs: + results.append(self.launch_run_prediction_charge(...)) # fan out +for try_soc in try_socs: + resultmid[try_soc] = results.pop(0).get() # then collect +``` + +`DummyThread` exists purely so the non-pooled path mimics that shape. So **the call sites do not need +to change at all** — only what `launch_*` returns and when the work actually happens. + +### Lazy batch + +- `launch_run_prediction_*` stops running anything. It appends a job to a pending list on the + `Prediction` and returns a `BatchHandle(batch, index)`. +- `BatchHandle.get()` flushes the whole pending batch on first call, then returns its own slot. + Subsequent `get()`s read already-computed results. +- Flush: resolve prediction-cache hits in Python first, marshal only the misses into a + `PkBatchJob` array, one `pk_run_batch` call, then shape each job's result. + +Batch sizes this produces (scenario 0, from the profile): + +``` +launch_run_prediction_charge 10,698 +launch_run_prediction_export 5,436 +launch_run_prediction_single 4,752 +launch_run_prediction_charge_min_max 3,294 + ------ + 24,180 launches, ~19,209 reaching the kernel +``` +`optimise_charge_limit_price_threads` fans out ~1176 at a time (392 candidates x 3 PV scenarios), +`optimise_charge_limit` ~900, `optimise_export` ~628. Those are the batches. + +### Do not duplicate the input preparation + +Each `thread_run_prediction_*` does three things: build the trial inputs, call `run_prediction`, +shape the result. The batch path needs the first and third but not the second. + +**Split them rather than copying them**, so the direct and batch paths cannot drift: + +```python +def _prepare_charge(self, try_soc, window_n, charge_limit, all_n): + """Build the trial charge limits - shared by thread_run_prediction_charge and the batch path.""" + try_charge_limit = charge_limit.copy() + if all_n: + for set_n in all_n: + try_charge_limit[set_n] = try_soc + else: + try_charge_limit[window_n] = try_soc + return try_charge_limit +``` + +Same for export (`export_limits.copy()` plus the private window copy — see traps) and single +(pass-through). Then `thread_run_prediction_*` becomes prepare + `run_prediction` + shape, and the +batch enqueue is prepare + record. + +### min/max jobs + +`thread_run_prediction_charge_min_max` scans `predict_soc` across the charge window to get +`min_soc`/`max_soc`. The kernel now does this itself so the batch does not have to ship an +8928-entry SoC buffer per job (that would be ~84MB on a large batch). Set on the job: + +```python +predict_minute_start = max(int((window["start"] - self.minutes_now) / 5) * 5, 0) +predict_minute_end = int((window["end"] - self.minutes_now) / 5) * 5 +job.soc_range_start_step = predict_minute_start // 5 +job.soc_range_end_step = predict_minute_end // 5 # inclusive +``` + +and read `result.soc_range_min` / `result.soc_range_max` back. + +**When `all_n` is set, Python skips the scan and returns `(soc_max, 0)` unclamped.** Pass +`soc_range_start_step = -1` for those; the kernel returns exactly `(soc_max, 0)` in that case (this +is what `f813d219` fixed). + +### Fallbacks that must keep working + +The batch path only applies when the kernel can run the job. Fall back to running the job through +the existing `thread_run_prediction_*` path, serially, when any of: + +- `KERNEL_HAS_BATCH` is False (binary predates `pk_run_batch` — the loader probes for the symbol) +- `kernel_supported()` is False for the job (no kernel context, `debug_enable`, or a `save` run) +- `pk_run_batch` returns non-zero, or a job's `status` field is non-zero + +A per-job `status` is returned precisely so one malformed scenario cannot discard the fan-out. + +## Traps found the hard way + +1. **`thread_run_prediction_export` used to mutate the caller's window dict** (`export_window[n]["start"] = start`). + That was only safe because each pool worker mutated its own unpickled copy. Any shared-memory + parallelism needs it local. The fix is on branch `perf/threadpool-prototype`: + ```python + export_window = list(export_window) + export_window[window_n] = dict(window, start=start) + ``` + Only `["end"]` is ever read back by `optimise_export`, so nothing depends on the write being + visible. **Port this across.** + +2. **`round_py` is poison in any hot loop.** It is `snprintf`+`strtod`, ~96ns, and serialises on + libc's global locale — with constant work per thread it degrades **17x at 8 threads**. Two calls + remain (`iboost_next`, `car_soc_next`), both once per run, both harmless. Do not add more. + +3. **The prediction cache is worth keeping.** ~6,518 of 25,727 calls are hits (44%), saving far more + than the hashing costs. Resolve hits in Python before building the batch. + +4. **Test isolation.** Any new test that calls `calculate_plan` must not use the shared `my_predbat` + fixture — it arrives carrying whatever earlier tests left on it and `calculate_plan` raises. Follow + `run_annual_integration_isolated` / `run_window_cache_tests_isolated`: take a fresh instance from + `create_predbat()` and load a debug YAML. + +5. **`cd` in a Bash tool call does not persist**, and `git checkout` carries uncommitted changes + across branches. Both bit during this session. + +## Verification protocol + +Non-negotiable, in this order: + +```bash +cd coverage && source setup.csh + +# 1. byte-identical plans - the real gate +python3 ../apps/predbat/unit_test.py --random-run \ + --random-template cases/predbat_debug_agile1.yaml \ + --random-scenarios cases/random_scenarios.yaml +python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json +# require: 20 unchanged, +0.0000 on metric, cost and all three PV futures + +# 2. kernel parity (includes the SoC bucket table check) +./run_all --test kernel_parity + +# 3. full suite including slow tests +./run_all + +# 4. quality gates +./run_pre_commit # re-run after the dictionary auto-sorts, then re-stage +``` + +Benchmark by summing `runtime_s` across the 20 scenarios, best of 3. Run-to-run spread is ~2-6%, so +do not trust a single run — that mistake was made earlier in this work and produced a bogus 18% +"win" that turned out to be noise. + +## Suggested order + +1. Port the `thread_run_prediction_export` mutation fix from `perf/threadpool-prototype`. +2. Split `thread_run_prediction_*` into `_prepare_*` + shaping. **Verify parity here** — this step + alone should be a no-op. +3. Add `BatchRunner` / `BatchHandle` and switch `launch_*` to enqueue. Keep `n_threads=1`. + **Verify parity.** This isolates the marshalling win with no concurrency risk. +4. Turn on threading (`n_threads` from the `threads` config). **Verify parity again** — results were + bit-identical at every thread count in the C-level test, so any divergence here is a Python bug. +5. Only then remove the process pool, `wrapped_run_prediction_*`, `PRED_GLOBAL` and `DummyThread`. + +## Dead ends - do not repeat these + +- **Python `ThreadPool` instead of the process pool.** `pk_run` does release the GIL (`ctypes.CDLL`) + and the kernel is reentrant, but per-call Python overhead makes the parallel fraction too small. + Peaks at **1.15x on two threads** then degrades below serial. Recorded with measurements on branch + `perf/threadpool-prototype` (commit message, marked do-not-merge). +- **The process pool itself.** 1.11x on 16 cores; the parent's per-call pickling is a serial + bottleneck. Removing it costs almost nothing. +- **Expecting the batch call itself to be faster.** `pk_run_batch` vs a loop of `pk_run` over 120 + scenarios measured **0.99x**. The C boundary crossing was never the cost. The batch is worth doing + for the Python-side savings and because it is the only way to use threads — not for the call + itself. + +## Related work in flight + +`PR #4536` (`perf/window-bounds-cache`) caches window start/end arrays and the prediction-cache key +tuple, worth **-21%** on its own and independent of this branch. It should compose: it removes Python +per-call work, this removes C++ per-call work. If both land, re-profile before assuming what is left. + +Note that batching **partly subsumes** the window-bounds cache, since a batch ships window bounds once +rather than per call. The `sim_hash` half still matters. From 6693c3410be51388274e1049ef1fa7355ed36f21 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 18:50:51 +0100 Subject: [PATCH 06/24] docs: plan for batching the prediction fan-out from Python Working plan for Phase B of the kernel batch work: launch_run_prediction_* queues jobs that a single pk_run_batch call runs per fan-out, which is both where the remaining Python overhead goes and the only shape that lets the kernel use threads. Co-Authored-By: Claude Opus 5 (1M context) --- .../2026-08-15-phase-b-batch-prediction.md | 1589 +++++++++++++++++ 1 file changed, 1589 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md diff --git a/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md b/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md new file mode 100644 index 000000000..33406d018 --- /dev/null +++ b/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md @@ -0,0 +1,1589 @@ +# Phase B: Batch Prediction Fan-Out Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Make `launch_run_prediction_*` queue work into a lazily-flushed batch that reaches the C++ kernel through one `pk_run_batch` call per fan-out, so the per-call Python overhead is paid once per batch and the kernel's threading can finally be used. + +**Architecture:** The four `launch_run_prediction_*` call sites in `plan.py` are already launch-all-then-collect-all, so they do not change shape. `launch_*` stops running anything: it prepares the trial inputs, appends a `BatchJob` to a pending list on the `Prediction`, and returns a `BatchHandle`. The first `BatchHandle.get()` flushes the whole pending batch — prediction-cache hits are resolved in Python, the misses are marshalled into one `PkBatchJob` array and run by a single `pk_run_batch` call (optionally multi-threaded inside C++), and each job's result is then shaped into exactly what its `thread_run_prediction_*` used to return. Anything the kernel cannot take falls back to the existing Python path, per job. + +**Tech Stack:** Python 3 (ctypes), C++ prediction kernel (`prediction_kernel.cpp`, ABI 3, parity revision 5, already built and committed), predbat's own `unit_test.py` harness. + +**Spec:** [PHASE_B_BATCH_REFACTOR.md](../../../PHASE_B_BATCH_REFACTOR.md) — the working brief this plan implements. Read it first; it carries the measurements, the traps and the dead ends that justify the design below. + +## Global Constraints + +- **Branch:** `perf/kernel-batch-abi` (4 commits, unpushed, based on `main`). All work continues on this branch. +- **No C++ changes.** The kernel side is done, verified and committed. If you find yourself editing `prediction_kernel.cpp`, stop — that means the design has drifted. (The one exception would be a genuine kernel bug, which then needs `PK_PARITY_REVISION` **and** `KERNEL_PARITY_REVISION` bumped and all 6 shipped binaries rebuilt.) +- **Byte-identical plans are the gate.** Every task that can change results must end with the 20-scenario comparison showing `20 unchanged, +0.0000` on metric, cost and all three PV futures. +- **Line length:** 256 chars (Black), 250 (Flake8). +- **Docstrings:** 100% coverage required (`interrogate`) — every function, method and class, including `__init__`. +- **Spelling:** British English (`en-gb`) via CSpell. New words go in `.cspell/custom-dictionary-workspace.txt`, which is auto-sorted on commit — re-stage after running pre-commit. +- **Naming:** `lower_case_with_underscores`. +- **Unit tests are mandatory for all new code** (CLAUDE.md), registered in `TEST_REGISTRY` in `apps/predbat/unit_test.py`. +- **Test output goes to a file, then you grep the file.** Never pipe a test run straight into grep — a wrong pattern means running it all again. +- **`cd` does not persist between Bash tool calls.** Every command below is written to be pasted whole. +- **Do not `git checkout` between branches with uncommitted work** — it carries the changes across. Commit first. + +## Invariant this design depends on + +**No caller may mutate a list or window dict it has passed to `launch_run_prediction_*` between that call and the matching `.get()`.** + +Today every launch either runs immediately (serial path) or pickles its arguments immediately (pool path), so this invariant did not exist. Batching defers the read to flush time, so it does now. All four call sites were read and already satisfy it, *after* Task 1 removes the one violation: + +| call site | fan-out | why it is safe | +|---|---|---| +| `plan.py:528-530` (`optimise_levels`) | `launch_run_prediction_single` ×3 | `try_charge_limit`/`try_export` are freshly materialised per scenario and never written again | +| `plan.py:1781-1799` (`optimise_charge_limit`) | `launch_run_prediction_charge_min_max` ×4-6 | `charge_limit`/`export_limits` are read-only across the block | +| `plan.py:1950-1955` (`optimise_charge_limit`) | `launch_run_prediction_charge` ×2-3 per SoC | `try_charge_limit` is a separate list, only written in the results loop *after* every `.get()` | +| `plan.py:2183-2186` (`optimise_export`) | `launch_run_prediction_export` ×2-3 per option | **violates it today** via `export_window[window_n]["start"] = start` — Task 1 fixes this | + +The 20-scenario byte-identical gate is what enforces the invariant in practice: any violation shows up as a changed plan immediately. + +## File Structure + +| File | Responsibility | Change | +|---|---|---| +| `apps/predbat/prediction_kernel.py` | ctypes/ABI layer only. Gains `BatchJob` (the queued-job record), `run_prediction_kernel_batch()` and `kernel_result_tuple()`; `pk_run_batch`'s argtypes get their missing `n_threads`. | Modify | +| `apps/predbat/prediction_batch.py` | **New.** `PredictionBatch` mixin (pending list, enqueue, flush, per-job Python fallback), `BatchHandle`, `prediction_cache_key()`. Imports `prediction_kernel` and `const` only — never `prediction`, so there is no import cycle. | Create | +| `apps/predbat/prediction.py` | `Prediction` gains the `PredictionBatch` mixin, the `_prepare_*` input builders shared by the direct and batch paths, `scan_soc_range()`, and the four `queue_run_prediction_*` entry points. | Modify | +| `apps/predbat/plan.py` | The four `launch_run_prediction_*` become one-line delegations to `queue_run_prediction_*`; the process pool goes away. | Modify | +| `apps/predbat/tests/test_kernel_parity.py` | Gains `run_batch_parity_tests()` — `pk_run_batch` against a loop of `pk_run`, at several thread counts. | Modify | +| `apps/predbat/tests/test_prediction_batch.py` | **New.** The batch runner's behaviour: equivalence with the direct path for all four kinds, laziness, dedup, cache hits, and both fallback routes. | Create | +| `apps/predbat/unit_test.py` | Register `prediction_batch` in `TEST_REGISTRY`. | Modify | +| `docs/apps-yaml.md` | `threads` changes meaning: kernel threads, not worker processes. | Modify | + +--- + +### Task 1: Stop the export trial mutating the caller's window + +**Files:** +- Modify: `apps/predbat/prediction.py:358-373` (`thread_run_prediction_export`) +- Test: `apps/predbat/tests/test_prediction_batch.py` (created here, one test; the rest of the file lands in Task 4) +- Modify: `apps/predbat/unit_test.py` (register the new test) + +**Interfaces:** +- Consumes: nothing from earlier tasks. +- Produces: `thread_run_prediction_export` no longer writes to `export_window[window_n]["start"]`. Task 3 splits this same function, and Task 4 relies on the window list being safe to hold across a deferred flush. + +This is the fix from `perf/threadpool-prototype` (`263f8178`, marked do-not-merge), ported across. It was only ever safe because each pool worker mutated its own unpickled copy. + +- [ ] **Step 1: Write the failing test** + +Create `apps/predbat/tests/test_prediction_batch.py`: + +```python +# ----------------------------------------------------------------------------- +# Predbat Home Battery System +# Copyright Trefor Southwell 2026 - All Rights Reserved +# This application maybe used for personal use only and not for commercial use +# ----------------------------------------------------------------------------- +# fmt off +# pylint: disable=consider-using-f-string +# pylint: disable=line-too-long + +"""Tests for the batched prediction fan-out. + +launch_run_prediction_* no longer runs anything: it queues a job on the Prediction and returns a +handle whose first get() flushes the whole batch through one pk_run_batch call. These tests pin the +two things that makes conditional - that a queued job returns exactly what the direct +thread_run_prediction_* path returns, and that a job the kernel cannot take still runs. +""" + +import random + +from prediction import Prediction + + +def make_export_windows(minutes_now): + """Build a small deterministic export window layout for the trial-input tests""" + return [ + {"start": minutes_now + 60, "end": minutes_now + 120, "average": 15.0}, + {"start": minutes_now + 180, "end": minutes_now + 240, "average": 20.0}, + ] + + +def test_export_trial_does_not_mutate_caller_window(my_predbat): + """The export trial must build its own window list, returns True on failure. + + It used to write the trial start straight into the caller's window dict, which was only safe + because each pool worker mutated its own unpickled copy. A batched fan-out holds one shared list + across every job in the batch, so an in-place write would corrupt every other trial of the same + window. + """ + print("**** Running export trial input tests ****") + failed = False + minutes_now = my_predbat.minutes_now + export_window = make_export_windows(minutes_now) + export_limits = [100.0, 100.0] + original = [dict(window) for window in export_window] + + prediction = Prediction(my_predbat, {}, {}, {}, {}) + trial_window, trial_limits = prediction._prepare_export(5.0, minutes_now + 90, 0, export_window, export_limits, None) + + if export_window != original: + print("ERROR: _prepare_export mutated the caller's export window: {} vs {}".format(export_window, original)) + failed = True + if export_limits != [100.0, 100.0]: + print("ERROR: _prepare_export mutated the caller's export limits: {}".format(export_limits)) + failed = True + if trial_window[0]["start"] != minutes_now + 90: + print("ERROR: trial window start not applied, got {}".format(trial_window[0]["start"])) + failed = True + if trial_window[1] is not export_window[1]: + print("ERROR: untouched windows should be shared with the caller's list, not copied") + failed = True + if trial_limits[0] != 5.0: + print("ERROR: trial export limit not applied, got {}".format(trial_limits[0])) + failed = True + + # The trial start is clamped to at least 5 minutes before the window end + trial_window, _ = prediction._prepare_export(5.0, minutes_now + 200, 0, export_window, export_limits, None) + if trial_window[0]["start"] != minutes_now + 115: + print("ERROR: trial window start not clamped to end-5, got {}".format(trial_window[0]["start"])) + failed = True + + if not failed: + print("Export trial input tests passed") + return failed + + +def run_prediction_batch_tests(my_predbat): + """Run every batched prediction test, returns True on failure""" + failed = test_export_trial_does_not_mutate_caller_window(my_predbat) + if failed: + print("**** Prediction batch tests FAILED ****") + else: + print("**** Prediction batch tests passed ****") + return failed +``` + +The test is written against `_prepare_export`, which does not exist yet — Step 4 of this task creates it, because extracting the helper *is* the fix: it is the only way to build the trial window without touching the caller's. Task 3 later joins the other three `thread_run_prediction_*` to the same pattern. + +- [ ] **Step 2: Register the test** + +In `apps/predbat/unit_test.py`, add the import next to the other test imports (they are alphabetical-ish, grouped by module): + +```python +from tests.test_prediction_batch import run_prediction_batch_tests +``` + +and add the registry entry to `TEST_REGISTRY`, next to the other prediction entries: + +```python + ("prediction_batch", run_prediction_batch_tests, "Batched prediction fan-out tests", False), +``` + +- [ ] **Step 3: Run the test to verify it fails** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test prediction_batch > /tmp/predbat-task1.log 2>&1; grep -nE "ERROR|FAIL|PASS|Traceback|AttributeError" /tmp/predbat-task1.log | head -20 +``` + +Expected: `AttributeError: 'Prediction' object has no attribute '_prepare_export'`. + +- [ ] **Step 4: Add `_prepare_export` and route the direct path through it** + +In `apps/predbat/prediction.py`, add the helper immediately above `thread_run_prediction_export`: + +```python + def _prepare_export(self, this_export_limit, start, window_n, export_window, export_limits, all_n): + """Build the trial export limits and window list - shared by thread_run_prediction_export and the batch path. + + The trial start is applied to a private copy of the window rather than written into the + caller's list: with a process pool each worker mutated its own unpickled copy, but a batched + fan-out shares one list across every job in the batch, so an in-place write would corrupt the + other trials of the same window. Only ["end"] is ever read back by the caller + (optimise_export), so nothing depends on the write being visible. + """ + export_limits = export_limits.copy() + + if all_n: + for window_id in all_n: + export_limits[window_id] = this_export_limit + else: + export_limits[window_n] = this_export_limit + # Adjust start + window = export_window[window_n] + start = min(start, window["end"] - 5) + export_window = list(export_window) + export_window[window_n] = dict(window, start=start) + + return export_window, export_limits +``` + +and replace the head of `thread_run_prediction_export` (everything from `# Store try value into the window` down to the line before the `(` of the result unpack) with: + +```python + export_window, export_limits = self._prepare_export(this_export_limit, start, window_n, export_window, export_limits, all_n) +``` + +- [ ] **Step 5: Run the test to verify it passes** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test prediction_batch > /tmp/predbat-task1.log 2>&1; grep -nE "ERROR|FAIL|passed|Traceback" /tmp/predbat-task1.log | head -20 +``` + +Expected: `Export trial input tests passed`, no ERROR lines. + +- [ ] **Step 6: Verify plans are byte-identical** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-task1-run.log 2>&1; python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json > /tmp/predbat-task1-cmp.log 2>&1; tail -30 /tmp/predbat-task1-cmp.log +``` + +Expected: 20 scenarios unchanged, `+0.0000` on metric, cost, and all three PV futures. Anything else means the mutation *was* being depended on — stop and investigate before continuing. + +- [ ] **Step 7: Run the full suite** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all > /tmp/predbat-task1-all.log 2>&1; grep -nE "FAILED|ERROR|Traceback|All tests passed|tests passed" /tmp/predbat-task1-all.log | tail -20 +``` + +- [ ] **Step 8: Commit** + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit && git add apps/predbat/prediction.py apps/predbat/tests/test_prediction_batch.py apps/predbat/unit_test.py && git commit -m "fix(prediction): build the export trial window privately instead of mutating the caller's + +The trial start was written straight into the caller's window dict, which was only safe because each +pool worker mutated its own unpickled copy. A batched fan-out shares one window list across every job +in the batch, so this has to be local. Ported from perf/threadpool-prototype. + +Co-Authored-By: Claude Opus 5 (1M context) " +``` + +(If pre-commit rewrites the cspell dictionary, `git add` it and re-run the commit.) + +--- + +### Task 2: Batch entry point in the ctypes layer + +**Files:** +- Modify: `apps/predbat/prediction_kernel.py:287-292` (argtypes), `:596-629` (result assembly) +- Test: `apps/predbat/tests/test_kernel_parity.py` + +**Interfaces:** +- Consumes: `PkBatchJob`, `PkBatchResult`, `KERNEL_HAS_BATCH` (already present on this branch). +- Produces: + - `class BatchJob` — the queued-job record, with `__slots__` `("charge_limit", "charge_window", "export_window", "export_limits", "pv_scenario", "end_record", "step", "soc_range_start_step", "soc_range_end_step", "sim_hash", "want_range", "range_window", "result")`. + - `kernel_result_tuple(pred, result, predict_soc) -> tuple` — the 17-field `run_prediction()` result tuple built from a `PkResult`. + - `run_prediction_kernel_batch(pred, jobs, n_threads=1) -> list | None` — returns one `(result_tuple_or_None, soc_range_min, soc_range_max)` per job in job order, or `None` if the whole batch could not run. + +**The bug this task fixes first:** `pk_run_batch` is declared in C++ as +`int32_t pk_run_batch(int64_t handle, const PkBatchJob *jobs, int32_t n_jobs, PkBatchResult *results, int32_t n_threads)` +but `prediction_kernel.py:289` gives it only four `argtypes`. Nothing calls it yet so nothing has broken, but a call built against that binding hands the C++ side an undefined `n_threads`. + +- [ ] **Step 1: Write the failing test** + +Add to `apps/predbat/tests/test_kernel_parity.py`: + +```python +def build_batch_jobs(my_predbat, rng, count): + """Build a list of BatchJob scenarios plus the Prediction they run against""" + apply_random_scenario(my_predbat, rng) + pv_step, pv10_step, load_step, load10_step = make_step_data(my_predbat, rng) + my_predbat.prediction_kernel_enable = True + prediction = Prediction(my_predbat, pv_step, pv10_step, load_step, load10_step) + prediction.kernel_handle = create_kernel_context(prediction) + + charge_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) + export_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) + end_record = my_predbat.forecast_minutes + + jobs = [] + for index in range(count): + charge_limit = [round(rng.uniform(0, my_predbat.soc_max), 2) for _ in charge_window] + export_limits = [rng.choice([100.0, 99.0, 0.0, round(rng.uniform(1, 99), 1)]) for _ in export_window] + pv_scenario = rng.choice([PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90]) + # Every third job asks for the SoC range over a charge window, as the min/max fan-out does + range_window = charge_window[index % len(charge_window)] if (index % 3) == 0 else None + start_step = -1 + end_step = -1 + if range_window is not None: + start_step = max(int((range_window["start"] - my_predbat.minutes_now) / 5) * 5, 0) // 5 + end_step = int((range_window["end"] - my_predbat.minutes_now) / 5) * 5 // 5 + jobs.append( + prediction_kernel.BatchJob( + charge_limit, + charge_window, + export_window, + export_limits, + pv_scenario, + end_record, + 5, + soc_range_start_step=start_step, + soc_range_end_step=end_step, + want_range=range_window is not None, + range_window=range_window, + ) + ) + return prediction, jobs + + +def run_batch_parity_tests(my_predbat, count=60): + """Check pk_run_batch matches a loop of pk_run exactly, at every thread count, returns True on failure. + + The batch path is the only one Python will use after this refactor, and it is the only one that + can run scenarios concurrently, so it is checked against the single-scenario path it replaces + rather than against the Python engine (which run_random_sweep_tests already pins pk_run against). + Results must be bit-identical, not merely close: the whole point of the fan-out is that plans do + not change. + """ + print("**** Running kernel batch parity tests ****") + if not prediction_kernel.KERNEL_HAS_BATCH: + print("SKIP: kernel does not expose pk_run_batch") + return False + + failed = False + prediction, jobs = build_batch_jobs(my_predbat, random.Random(4321), count) + if not prediction.kernel_handle: + print("ERROR: batch parity kernel context creation failed") + return True + + # Reference: one pk_run per scenario, with the SoC series materialised so the range can be + # scanned in Python exactly as thread_run_prediction_charge_min_max does + reference = [] + for job in jobs: + single = run_prediction_kernel(prediction, job.charge_limit, job.charge_window, job.export_window, job.export_limits, job.pv_scenario, job.end_record, 5, False) + if single is None: + print("ERROR: reference pk_run failed") + return True + if job.range_window is None: + soc_range = (prediction.soc_max, 0) + else: + soc_range = prediction.scan_soc_range(single[11], job.range_window) + reference.append((single, soc_range)) + + for n_threads in (1, 2, 4, 8): + batched = prediction_kernel.run_prediction_kernel_batch(prediction, jobs, n_threads) + if batched is None: + print("ERROR: pk_run_batch failed at {} threads".format(n_threads)) + return True + if len(batched) != len(jobs): + print("ERROR: pk_run_batch returned {} results for {} jobs".format(len(batched), len(jobs))) + return True + for index, (result_tuple, soc_range_min, soc_range_max) in enumerate(batched): + single, (expect_min, expect_max) = reference[index] + if result_tuple is None: + print("ERROR: job {} reported a non-zero status at {} threads".format(index, n_threads)) + failed = True + continue + for field, name in enumerate(RESULT_NAMES): + if result_tuple[field] != single[field]: + print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) + failed = True + # The batch never materialises the SoC series - that is what makes it affordable + if result_tuple[11] != {}: + print("ERROR: job {} returned a SoC series from the batch path".format(index)) + failed = True + for field, name in [(12, "car_charging_soc_next"), (13, "iboost_next"), (14, "iboost_running"), (15, "iboost_running_solar"), (16, "iboost_running_full")]: + if result_tuple[field] != single[field]: + print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) + failed = True + if soc_range_min != expect_min or soc_range_max != expect_max: + print("ERROR: job {} at {} threads SoC range {} {} expected {} {}".format(index, n_threads, soc_range_min, soc_range_max, expect_min, expect_max)) + failed = True + + if not failed: + print("Batch parity: {} scenarios bit-identical to pk_run at 1, 2, 4 and 8 threads".format(count)) + return failed +``` + +and call it from `run_kernel_parity_tests`, after the clipping sweep: + +```python + if not failed: + failed |= run_batch_parity_tests(my_predbat) +``` + +The test uses `prediction.scan_soc_range`, which Task 3 creates. Add it in this task as part of Step 4 (Task 3 then routes `thread_run_prediction_charge_min_max` through it). + +- [ ] **Step 2: Run the test to verify it fails** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test kernel_parity > /tmp/predbat-task2.log 2>&1; grep -nE "ERROR|FAIL|Traceback|AttributeError|passed" /tmp/predbat-task2.log | head -20 +``` + +Expected: `AttributeError: module 'prediction_kernel' has no attribute 'BatchJob'`. + +- [ ] **Step 3: Fix the `pk_run_batch` binding** + +In `apps/predbat/prediction_kernel.py`, replace the argtypes line inside the `try:` at line 288-289: + +```python + lib.pk_run_batch.restype = ctypes.c_int32 + # The trailing c_int32 is n_threads - pk_run_batch takes five arguments, and ctypes + # will happily pass a fourth-and-a-bit if the binding says otherwise + lib.pk_run_batch.argtypes = [ctypes.c_int64, ctypes.POINTER(PkBatchJob), ctypes.c_int32, ctypes.POINTER(PkBatchResult), ctypes.c_int32] +``` + +- [ ] **Step 4: Add `BatchJob`, `kernel_result_tuple`, `run_prediction_kernel_batch` and `scan_soc_range`** + +In `apps/predbat/prediction_kernel.py`, add `BatchJob` after the `PkBatchResult` class: + +```python +class BatchJob: + """One queued prediction: its trial inputs, how the result should be shaped, and the result itself. + + run_prediction_kernel_batch reads only the input fields and the SoC range steps. sim_hash, + want_range, range_window and result belong to the batch runner in prediction_batch.py, which is + the only thing that creates these; they live here so the ctypes layer can be tested on its own. + """ + + __slots__ = ("charge_limit", "charge_window", "export_window", "export_limits", "pv_scenario", "end_record", "step", "soc_range_start_step", "soc_range_end_step", "sim_hash", "want_range", "range_window", "result") + + def __init__(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, soc_range_start_step=-1, soc_range_end_step=-1, sim_hash=None, want_range=False, range_window=None): + """Record one job's trial inputs; result stays None until the batch is flushed""" + self.charge_limit = charge_limit + self.charge_window = charge_window + self.export_window = export_window + self.export_limits = export_limits + self.pv_scenario = pv_scenario + self.end_record = end_record + self.step = step + self.soc_range_start_step = soc_range_start_step + self.soc_range_end_step = soc_range_end_step + self.sim_hash = sim_hash + self.want_range = want_range + self.range_window = range_window + self.result = None +``` + +Then factor the result assembly out of `run_prediction_kernel` so the single and batch paths cannot drift. Add: + +```python +def kernel_result_tuple(pred, result, predict_soc): + """Assemble the 17-field Prediction.run_prediction() result tuple from a PkResult. + + Shared by the single-scenario and batch paths - mirrors prediction.py:626-628, 1266-1284. + """ + car_charging_soc_next = pred.car_charging_soc_next[:] + if result.car_soc_next_valid: + for car_n in range(pred.num_cars): + car_charging_soc_next[car_n] = result.car_soc_next[car_n] + + iboost_next = result.iboost_next if pred.iboost_enable else pred.iboost_next + + return ( + round(result.final_metric, 4), + round(result.import_kwh_battery, 4), + round(result.import_kwh_house, 4), + round(result.export_kwh, 4), + round(result.soc_min, 4), + round(result.final_soc, 4), + result.soc_min_minute, + round(result.battery_cycle, 4), + round(result.metric_keep, 4), + round(result.final_iboost, 4), + round(result.final_carbon_g, 4), + predict_soc, + car_charging_soc_next, + iboost_next, + bool(result.iboost_running), + bool(result.iboost_running_solar), + bool(result.iboost_running_full), + ) + + +def reset_kernel_run_state(pred): + """Clear the per-run state attributes exactly as the Python engine does - prediction.py:414-422 + + Non-save runs never populate these, so they simply stay empty/False; a kernel run has to leave + the Prediction in the same state a Python run would. + """ + pred.predict_soc_best = {} + pred.predict_metric_best = {} + pred.predict_iboost_best = {} + pred.predict_carbon_best = {} + pred.predict_clipped_best = {} + pred.iboost_running = False + pred.iboost_running_solar = False + pred.iboost_running_full = False + + +def run_prediction_kernel_batch(pred, jobs, n_threads=1): + """Run a whole fan-out of prediction scenarios through the kernel in one pk_run_batch call. + + Returns a list of (result_tuple, soc_range_min, soc_range_max) in job order, where result_tuple + is the same 17-field tuple Prediction.run_prediction() returns, or None for a job the kernel + refused - the caller re-runs those through the Python engine. Returns None when the batch could + not be run at all (no kernel, no batch entry point, or a non-zero return code). + + Whether the kernel is allowed to answer at all is the caller's decision, not this function's: + kernel_supported() also refuses debug and saving runs, and flush_batch checks it before getting + here. + + Batched jobs never materialise the per-minute SoC series: their callers all discard it, and one + buffer per job would be ~84MB on a large batch. The one thing a caller does want from it - the + SoC range across a charge window - the kernel tracks inline over + [soc_range_start_step, soc_range_end_step] instead. + """ + lib = KERNEL_LIB + if not lib or not KERNEL_HAS_BATCH or not getattr(pred, "kernel_handle", 0): + return None + + n_jobs = len(jobs) + job_array = (PkBatchJob * n_jobs)() + result_array = (PkBatchResult * n_jobs)() + # Every ctypes buffer behind a pointer field has to outlive the call. Structures reached through + # an array index do not keep their own _objects, so the buffers are held here rather than relying + # on ctypes' keepalive doing the right thing through the array. + buffers = [] + # A fan-out reuses the same window lists across most of its jobs, so their start/end arrays are + # marshalled once per distinct list instead of once per job - that is the bulk of the batching + # win. Keyed on identity, with the list retained so an id() cannot be recycled mid-batch. This + # relies on no caller mutating a window list between enqueue and flush (see prediction_batch.py). + window_cache = {} + + def window_arrays(windows): + """Marshal a window list's start/end arrays, reusing an earlier job's arrays where possible""" + entry = window_cache.get(id(windows)) + if entry is None: + entry = (int32_array([window["start"] for window in windows]), int32_array([window["end"] for window in windows]), windows) + window_cache[id(windows)] = entry + return entry + + for index, job in enumerate(jobs): + charge_start, charge_end, _ = window_arrays(job.charge_window) + export_start, export_end, _ = window_arrays(job.export_window) + charge_limit = double_array(job.charge_limit) + export_limits = double_array(job.export_limits) + buffers.append((charge_limit, export_limits)) + + pk_job = job_array[index] + pk_job.charge_limit = charge_limit + pk_job.charge_start = charge_start + pk_job.charge_end = charge_end + pk_job.export_limits = export_limits + pk_job.export_start = export_start + pk_job.export_end = export_end + pk_job.soc_out = None + pk_job.n_charge = len(job.charge_window) + pk_job.n_export = len(job.export_window) + pk_job.pv_scenario = int(job.pv_scenario) + pk_job.end_record = job.end_record + pk_job.step = PREDICT_STEP # the caller's step is ignored - see run_prediction_kernel + pk_job.soc_range_start_step = job.soc_range_start_step + pk_job.soc_range_end_step = job.soc_range_end_step + + return_code = lib.pk_run_batch(pred.kernel_handle, job_array, n_jobs, result_array, max(int(n_threads), 1)) + if return_code != 0: + return None + + reset_kernel_run_state(pred) + + results = [] + for index in range(n_jobs): + batch_result = result_array[index] + if batch_result.status != 0: + results.append((None, 0.0, 0.0)) + continue + results.append((kernel_result_tuple(pred, batch_result.result, {}), batch_result.soc_range_min, batch_result.soc_range_max)) + return results +``` + +Then rewrite the tail of `run_prediction_kernel` (from the `# Reset the per-run state attributes` comment to the end) to use the shared helpers: + +```python + reset_kernel_run_state(pred) + + # Assemble the same return value as the Python engine + predict_soc = {} + if not cache: + # Indexed loop, not dict(zip(range(...), soc_out)): iterating a ctypes array boxes each double + # through the sequence protocol and measured 34% slower than subscripting it. + for k in range(n_steps): + predict_soc[k * PREDICT_STEP] = soc_out[k] + + return kernel_result_tuple(pred, result, predict_soc) +``` + +Finally, add `scan_soc_range` to `Prediction` in `apps/predbat/prediction.py`, immediately above `thread_run_prediction_charge_min_max`: + +```python + def scan_soc_range(self, predict_soc, window): + """Return the (min, max) SoC across a charge window - shared by the direct and batch min/max paths. + + The kernel computes the same range inline (see PkBatchJob.soc_range_start_step), so this is + only reached when a job falls back to the Python engine; the two must agree exactly, including + the clamping that collapses an empty range to a single value rather than leaving min above max. + """ + min_soc = self.soc_max + max_soc = 0 + predict_minute_start = max(int((window["start"] - self.minutes_now) / 5) * 5, 0) + predict_minute_end = int((window["end"] - self.minutes_now) / 5) * 5 + for minute in range(predict_minute_start, predict_minute_end + 5, 5): + if minute in predict_soc: + min_soc = min(predict_soc[minute], min_soc) + max_soc = max(predict_soc[minute], max_soc) + max_soc = max(max_soc, min_soc) + min_soc = min(min_soc, max_soc) + return min_soc, max_soc +``` + +- [ ] **Step 5: Run the test to verify it passes** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test kernel_parity > /tmp/predbat-task2.log 2>&1; grep -nE "ERROR|FAIL|bit-identical|passed|Traceback" /tmp/predbat-task2.log | head -20 +``` + +Expected: `Batch parity: 60 scenarios bit-identical to pk_run at 1, 2, 4 and 8 threads`, and the parity suite passing. + +- [ ] **Step 6: Verify the single-scenario path still matches (the refactor above touched it)** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test model_kernel --test kernel_parity > /tmp/predbat-task2-model.log 2>&1; grep -nE "ERROR|FAILED|passed" /tmp/predbat-task2-model.log | tail -20 +``` + +- [ ] **Step 7: Commit** + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit && git add apps/predbat/prediction_kernel.py apps/predbat/prediction.py apps/predbat/tests/test_kernel_parity.py && git commit -m "feat(kernel): marshal a whole fan-out into one pk_run_batch call + +Adds BatchJob, run_prediction_kernel_batch and the shared result assembly, and gives pk_run_batch's +ctypes binding the n_threads argument it was missing. Window start/end arrays are marshalled once per +distinct window list rather than once per job, which is where the batching win comes from. + +Bit-identical to a loop of pk_run across 60 scenarios at 1, 2, 4 and 8 threads. + +Co-Authored-By: Claude Opus 5 (1M context) " +``` + +--- + +### Task 3: Split the trial-input building out of `thread_run_prediction_*` + +**Files:** +- Modify: `apps/predbat/prediction.py:227-394` (all four `thread_run_prediction_*`) + +**Interfaces:** +- Consumes: `_prepare_export` (Task 1), `scan_soc_range` (Task 2). +- Produces: + - `_prepare_single(charge_limit, export_limits) -> (list, list)` + - `_prepare_charge(try_soc, window_n, charge_limit, all_n) -> list` + - `_prepare_export(...)` — already exists from Task 1. + Task 4's `queue_run_prediction_*` call exactly these, so the direct and batch paths cannot drift. + +This step must be a **no-op**. It exists so the batch path never gets a second copy of the input building. + +- [ ] **Step 1: Add the two remaining prepare helpers** + +In `apps/predbat/prediction.py`, above `thread_run_prediction_single`: + +```python + def _prepare_single(self, charge_limit, export_limits): + """Copy the caller's limit lists for a single-scenario trial - shared by thread_run_prediction_single and the batch path. + + The copy used to live in Plan.launch_run_prediction_single, where it protected the caller's + lists from the pool pickling them; the batch path defers the read to flush time, which needs + the same protection, so it belongs with the other trial-input building. + """ + return list(charge_limit), list(export_limits) + + def _prepare_charge(self, try_soc, window_n, charge_limit, all_n): + """Build the trial charge limits - shared by thread_run_prediction_charge/_charge_min_max and the batch path""" + try_charge_limit = charge_limit.copy() + if all_n: + for set_n in all_n: + try_charge_limit[set_n] = try_soc + else: + try_charge_limit[window_n] = try_soc + return try_charge_limit +``` + +- [ ] **Step 2: Route the four thread functions through them** + +`thread_run_prediction_single` — insert as the first statement of the body: + +```python + charge_limit, export_limits = self._prepare_single(charge_limit, export_limits) +``` + +`thread_run_prediction_charge` and `thread_run_prediction_charge_min_max` — replace the five-line `try_charge_limit = charge_limit.copy()` block in each with: + +```python + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) +``` + +`thread_run_prediction_charge_min_max` — replace the scan block (`min_soc = self.soc_max` through `min_soc = min(min_soc, max_soc)`) with: + +```python + min_soc = self.soc_max + max_soc = 0 + if not all_n: + min_soc, max_soc = self.scan_soc_range(predict_soc, charge_window[window_n]) +``` + +`thread_run_prediction_export` — already routed through `_prepare_export` in Task 1. + +- [ ] **Step 3: Drop the now-duplicated copy in plan.py** + +`Plan.launch_run_prediction_single` in `apps/predbat/plan.py:675-676` still does its own `list()` copies. Delete those two lines — `_prepare_single` now owns that. + +- [ ] **Step 4: Verify the split changed nothing** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-task3-run.log 2>&1; python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json > /tmp/predbat-task3-cmp.log 2>&1; tail -30 /tmp/predbat-task3-cmp.log +``` + +Expected: 20 unchanged, `+0.0000` everywhere. This step alone should be a no-op — if it is not, the split is wrong. + +- [ ] **Step 5: Run the full suite** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all > /tmp/predbat-task3-all.log 2>&1; grep -nE "FAILED|ERROR|Traceback|tests passed" /tmp/predbat-task3-all.log | tail -20 +``` + +- [ ] **Step 6: Commit** + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit && git add apps/predbat/prediction.py apps/predbat/plan.py && git commit -m "refactor(prediction): split trial-input building out of thread_run_prediction_* + +Each thread_run_prediction_* built the trial inputs, ran the prediction and shaped the result. The +batch path needs the first and third but not the second, so they are split rather than copied - one +definition of what a trial input is, for both paths. + +No-op: 20 random scenarios byte-identical. + +Co-Authored-By: Claude Opus 5 (1M context) " +``` + +--- + +### Task 4: The lazy batch runner, serial + +**Files:** +- Create: `apps/predbat/prediction_batch.py` +- Modify: `apps/predbat/prediction.py` (mixin, `queue_run_prediction_*`, `prediction_cache_key` reuse, `__init__`) +- Modify: `apps/predbat/plan.py:671-714` (the four `launch_*`), `:27` (imports), `:1340-1365` (pool creation) +- Test: `apps/predbat/tests/test_prediction_batch.py` + +**Interfaces:** +- Consumes: `BatchJob`, `run_prediction_kernel_batch` (Task 2); `_prepare_single`, `_prepare_charge`, `_prepare_export`, `scan_soc_range` (Tasks 1 and 3). +- Produces: + - `prediction_batch.prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) -> int` + - `prediction_batch.BatchHandle` with `.get()` — the drop-in for `AsyncResult`/`DummyThread`. + - `prediction_batch.PredictionBatch` mixin: `enqueue_prediction(...) -> BatchHandle`, `flush_batch()`, `run_batch_job_python(job) -> tuple`, attributes `pending_batch` (list) and `batch_threads` (int). + - `Prediction.queue_run_prediction_single/_charge/_charge_min_max/_export` — same signatures as the matching `thread_run_prediction_*`, returning a `BatchHandle`. + +`batch_threads` stays at 1 for this whole task. That isolates the marshalling win with no concurrency in play, so any divergence here is a Python bug and nothing else. + +- [ ] **Step 1: Write the failing tests** + +Extend `apps/predbat/tests/test_prediction_batch.py` (keep the Task 1 test, add these). Import at the top: + +```python +import prediction_batch +from const import PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10 +from prediction_kernel import create_kernel_context +from tests.test_kernel_parity import apply_random_scenario, kernel_available, make_step_data, make_windows, restore_scenario_state, snapshot_scenario_state +``` + +```python +def make_batch_prediction(my_predbat, seed=7): + """Build a kernel-enabled Prediction plus a charge/export window layout to fan out over""" + rng = random.Random(seed) + apply_random_scenario(my_predbat, rng) + pv_step, pv10_step, load_step, load10_step = make_step_data(my_predbat, rng) + my_predbat.prediction_kernel_enable = True + prediction = Prediction(my_predbat, pv_step, pv10_step, load_step, load10_step) + prediction.kernel_handle = create_kernel_context(prediction) + charge_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, 4) + export_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, 4) + charge_limit = [round(my_predbat.soc_max / 2, 2)] * len(charge_window) + export_limits = [100.0] * len(export_window) + return prediction, charge_window, export_window, charge_limit, export_limits + + +def test_queued_matches_direct(my_predbat): + """Every queued prediction must return exactly what the direct thread path returns, returns True on failure""" + print("**** Running queued vs direct equivalence tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + try_soc = round(my_predbat.soc_max * 0.8, 2) + + cases = [ + ("single", lambda: prediction.thread_run_prediction_single(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record, 5), lambda: prediction.queue_run_prediction_single(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record, 5)), + ("charge", lambda: prediction.thread_run_prediction_charge(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_PV10, None, end_record), lambda: prediction.queue_run_prediction_charge(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_PV10, None, end_record)), + ("charge_min_max", lambda: prediction.thread_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), lambda: prediction.queue_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record)), + ("charge_min_max_all_n", lambda: prediction.thread_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, [0, 2], end_record), lambda: prediction.queue_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, [0, 2], end_record)), + ("export", lambda: prediction.thread_run_prediction_export(5.0, export_window[1]["start"] + 15, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), lambda: prediction.queue_run_prediction_export(5.0, export_window[1]["start"] + 15, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record)), + ] + + for name, direct_call, queue_call in cases: + # The queued run goes first, so the direct run cannot be answered out of the cache the queued + # one just populated - and vice versa, hence the clear between them + prediction.prediction_cache = {} + queued = queue_call().get() + prediction.prediction_cache = {} + direct = direct_call() + if queued != direct: + print("ERROR: {} queued {} != direct {}".format(name, queued, direct)) + failed = True + + if not failed: + print("Queued predictions match the direct path for all five shapes") + return failed + + +def test_batch_is_lazy(my_predbat): + """Nothing runs until the first get(), and one get() flushes the whole batch, returns True on failure""" + print("**** Running batch laziness tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + + handles = [prediction.queue_run_prediction_charge(round(soc, 2), 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for soc in (1.0, 2.0, 3.0)] + if len(prediction.pending_batch) != 3: + print("ERROR: expected 3 pending jobs, got {}".format(len(prediction.pending_batch))) + failed = True + if any(handle.job.result is not None for handle in handles): + print("ERROR: a job ran before its handle was read") + failed = True + + handles[0].get() + if prediction.pending_batch: + print("ERROR: pending batch not drained by the first get(), {} left".format(len(prediction.pending_batch))) + failed = True + if any(handle.job.result is None for handle in handles): + print("ERROR: one get() did not flush the whole batch") + failed = True + + # A second read must not re-run anything + before = handles[2].job.result + if handles[2].get() is not before: + print("ERROR: reading a handle twice recomputed the result") + failed = True + + if not failed: + print("Batch laziness tests passed") + return failed + + +def test_batch_cache_and_dedup(my_predbat): + """Cache hits and intra-batch duplicates must never reach the kernel, returns True on failure""" + print("**** Running batch cache/dedup tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + prediction.prediction_cache_enable = True + + calls = [] + real_batch = prediction_batch.run_prediction_kernel_batch + + def spy(pred, jobs, n_threads): + """Record how many jobs each batch call was handed, then run it for real""" + calls.append(len(jobs)) + return real_batch(pred, jobs, n_threads) + + prediction_batch.run_prediction_kernel_batch = spy + try: + # Three identical jobs in one batch must collapse to one kernel job + prediction.prediction_cache = {} + handles = [prediction.queue_run_prediction_charge(4.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for _ in range(3)] + results = [handle.get() for handle in handles] + if calls != [1]: + print("ERROR: expected one kernel job for three identical trials, got {}".format(calls)) + failed = True + if results[0] != results[1] or results[1] != results[2]: + print("ERROR: deduplicated jobs returned different results") + failed = True + + # And a repeat in a later batch must come from the cache without a kernel call at all + del calls[:] + again = prediction.queue_run_prediction_charge(4.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if calls: + print("ERROR: a cached scenario still reached the kernel: {}".format(calls)) + failed = True + if again != results[0]: + print("ERROR: cached result {} differs from the computed one {}".format(again, results[0])) + failed = True + finally: + prediction_batch.run_prediction_kernel_batch = real_batch + + if not failed: + print("Batch cache/dedup tests passed") + return failed + + +def test_batch_fallbacks(my_predbat): + """A job the kernel cannot take still runs, and gives the Python engine's answer, returns True on failure""" + print("**** Running batch fallback tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + + # Two references, because the fallbacks land on two different engines. A batch the kernel refused + # still re-runs through run_prediction, which dispatches to the kernel; a Prediction the kernel + # will not serve at all re-runs on the Python engine. Those two agree to 1e-6 (kernel_parity), not + # bit-exactly, so each fallback is compared against the engine it actually used. + prediction.prediction_cache = {} + expected = prediction.thread_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) + prediction.debug_enable = True + prediction.prediction_cache = {} + expected_python = prediction.thread_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) + prediction.debug_enable = False + + # 1. Whole batch refused (no kernel, stale binary, or a non-zero return code) + real_batch = prediction_batch.run_prediction_kernel_batch + + def refuse_all(pred, jobs, n_threads): + """Stand in for a kernel that cannot run the batch at all""" + return None + + def refuse_each(pred, jobs, n_threads): + """Stand in for a kernel that ran the batch but rejected every job""" + return [(None, 0.0, 0.0)] * len(jobs) + + for name, stub in (("whole batch", refuse_all), ("per job", refuse_each)): + prediction_batch.run_prediction_kernel_batch = stub + try: + prediction.prediction_cache = {} + got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if got != expected: + print("ERROR: {} fallback returned {} expected {}".format(name, got, expected)) + failed = True + finally: + prediction_batch.run_prediction_kernel_batch = real_batch + + # 2. Debug runs must not reach the kernel from the batch when the direct path would not take it + prediction.debug_enable = True + try: + prediction.prediction_cache = {} + got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if got != expected_python: + print("ERROR: debug_enable fallback returned {} expected {}".format(got, expected_python)) + failed = True + finally: + prediction.debug_enable = False + + # 3. Kernel genuinely unavailable for this Prediction + prediction.kernel_handle = 0 + prediction.prediction_cache = {} + got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if got != expected_python: + print("ERROR: kernel-less fallback returned {} expected {}".format(got, expected_python)) + failed = True + + if not failed: + print("Batch fallback tests passed") + return failed +``` + +and rewrite the runner at the bottom of the file: + +```python +def run_prediction_batch_tests(my_predbat): + """Run every batched prediction test, returns True on failure""" + failed = test_export_trial_does_not_mutate_caller_window(my_predbat) + + available, required_failure = kernel_available() + if not available: + print("WARNING: kernel not available - batch tests that need it are SKIPPED") + return failed or required_failure + + state = snapshot_scenario_state(my_predbat) + try: + failed |= test_queued_matches_direct(my_predbat) + failed |= test_batch_is_lazy(my_predbat) + failed |= test_batch_cache_and_dedup(my_predbat) + failed |= test_batch_fallbacks(my_predbat) + finally: + restore_scenario_state(my_predbat, state) + my_predbat.prediction_kernel_enable = False + + if failed: + print("**** Prediction batch tests FAILED ****") + else: + print("**** Prediction batch tests passed ****") + return failed +``` + +- [ ] **Step 2: Run the tests to verify they fail** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test prediction_batch > /tmp/predbat-task4.log 2>&1; grep -nE "ERROR|FAIL|Traceback|ModuleNotFound|AttributeError" /tmp/predbat-task4.log | head -20 +``` + +Expected: `ModuleNotFoundError: No module named 'prediction_batch'`. + +- [ ] **Step 3: Write `prediction_batch.py`** + +```python +# ----------------------------------------------------------------------------- +# Predbat Home Battery System +# Copyright Trefor Southwell 2026 - All Rights Reserved +# This application maybe used for personal use only and not for commercial use +# ----------------------------------------------------------------------------- +# fmt off +# pylint: disable=consider-using-f-string +# pylint: disable=line-too-long + +"""Lazy batching of the prediction fan-out. + +Every optimiser fan-out in plan.py is launch-all-then-collect-all, so the launches can queue instead +of running: each one prepares its trial inputs, appends a BatchJob and returns a BatchHandle, and the +first get() runs the whole batch through a single pk_run_batch call. That pays the Python/C boundary +and the window marshalling once per fan-out instead of once per scenario, and it is the only shape +that lets the kernel spread the work across cores - a Python thread pool cannot (the GIL serialises +it) and a process pool cannot (the parent's pickling is a serial bottleneck); both were measured and +rejected. + +INVARIANT: a caller must not mutate any list or window dict it has handed to a queue_* entry point +until it has read the matching handle. The four fan-outs in plan.py satisfy this; the 20-scenario +byte-identical plan comparison is what keeps it that way. +""" + +from operator import itemgetter + +from const import PREDICT_STEP +from prediction_kernel import BatchJob, kernel_supported, run_prediction_kernel_batch + +# Pulls (start, end) from a window dict; used to build the prediction cache key without a Python +# level loop over every window +window_bounds = itemgetter("start", "end") + + +def prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step): + """Hash a simulation's inputs into its prediction cache key. + + Shared by Prediction.run_prediction and the batch runner so a scenario cannot land under two + different keys depending on which path reached it. Built as one tuple hash to keep the per-window + hashing in C rather than looping in Python, which matters because it runs on every simulation + with a few hundred windows. + """ + return hash( + ( + tuple(charge_limit), + tuple(map(window_bounds, charge_window)), + tuple(export_limits), + tuple(map(window_bounds, export_window)), + pv_scenario, + end_record, + step, + ) + ) + + +def shape_batch_result(job, result, soc_range_min, soc_range_max): + """Shape a full run_prediction result into what this job's thread_run_prediction_* returned""" + shaped = tuple(result[:11]) + if job.want_range: + shaped = shaped + (soc_range_min, soc_range_max) + return shaped + + +class BatchHandle: + """Result handle for a queued prediction - the drop-in for the pool's AsyncResult""" + + __slots__ = ("pred", "job") + + def __init__(self, pred, job): + """Bind the handle to the Prediction that owns the batch and to its own job""" + self.pred = pred + self.job = job + + def get(self): + """Return this job's result, flushing the whole pending batch on the first call""" + if self.job.result is None: + self.pred.flush_batch() + return self.job.result + + +class PredictionBatch: + """Pending-batch state and flushing for Prediction. + + A mixin rather than a separate object so the pending list lives directly on the Prediction that + owns the kernel context, with no reference cycle between the two. + """ + + def enqueue_prediction(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, cache, want_range=False, range_window=None): + """Queue one prediction and return a handle to its eventual result""" + sim_hash = prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) if cache else None + + # The kernel tracks the SoC range itself over a step range, so a min/max job does not have to + # ship an 8928-entry SoC buffer. A negative start step means "no range asked for", which the + # kernel answers with (soc_max, 0) - exactly what the Python all_n path returns unclamped. + soc_range_start_step = -1 + soc_range_end_step = -1 + if range_window is not None: + predict_minute_start = max(int((range_window["start"] - self.minutes_now) / 5) * 5, 0) + predict_minute_end = int((range_window["end"] - self.minutes_now) / 5) * 5 + soc_range_start_step = predict_minute_start // PREDICT_STEP + soc_range_end_step = predict_minute_end // PREDICT_STEP + + job = BatchJob( + charge_limit, + charge_window, + export_window, + export_limits, + pv_scenario, + end_record, + step, + soc_range_start_step=soc_range_start_step, + soc_range_end_step=soc_range_end_step, + sim_hash=sim_hash, + want_range=want_range, + range_window=range_window, + ) + self.pending_batch.append(job) + return BatchHandle(self, job) + + def run_batch_job_python(self, job): + """Run one job through the normal prediction path, for when the kernel cannot take it""" + result = self.run_prediction(job.charge_limit, job.charge_window, job.export_window, job.export_limits, job.pv_scenario, end_record=job.end_record, step=job.step, cache=job.sim_hash is not None) + if not job.want_range: + return tuple(result[:11]) + if job.range_window is None: + return tuple(result[:11]) + (self.soc_max, 0) + return tuple(result[:11]) + self.scan_soc_range(result[11], job.range_window) + + def flush_batch(self): + """Run every pending job: cache hits first, then one kernel call, then any fallbacks""" + pending = self.pending_batch + if not pending: + return + # Cleared before anything runs, so a fallback that re-enters run_prediction cannot see a + # half-flushed batch or flush it a second time + self.pending_batch = [] + + cache = self.prediction_cache + kernel_jobs = [] + duplicates = [] + first_by_hash = {} + for job in pending: + if job.sim_hash is not None: + cached = cache.get(job.sim_hash) + if cached is not None: + job.result = shape_batch_result(job, cached, 0.0, 0.0) + continue + # Two identical trials in one fan-out used to be a cache hit for the second one; the + # batch has to collapse them itself or that hit is lost (~44% of calls are hits) + first = first_by_hash.get(job.sim_hash) + if first is not None: + duplicates.append((job, first)) + continue + first_by_hash[job.sim_hash] = job + kernel_jobs.append(job) + + if kernel_jobs: + # kernel_supported() is a property of the Prediction, not of the individual job - it also + # refuses debug runs, which would otherwise reach the kernel here when the direct path + # would have used the Python engine. save is always None for a queued job: a saving run + # calls run_prediction directly and never fans out. + batched = run_prediction_kernel_batch(self, kernel_jobs, self.batch_threads) if kernel_supported(self, None, PREDICT_STEP) else None + for index, job in enumerate(kernel_jobs): + entry = batched[index] if batched is not None else None + if entry is None or entry[0] is None: + job.result = self.run_batch_job_python(job) + continue + result, soc_range_min, soc_range_max = entry + if job.sim_hash is not None: + # Stored without the SoC/car data to save memory, mirroring run_prediction + cache[job.sim_hash] = result[:11] + ([], []) + result[13:] + job.result = shape_batch_result(job, result, soc_range_min, soc_range_max) + + for job, first in duplicates: + job.result = first.result +``` + +- [ ] **Step 4: Wire the mixin and the queue entry points into `Prediction`** + +In `apps/predbat/prediction.py`, replace the local `window_bounds` definition and the inline hash in `run_prediction` with the shared ones, and add the mixin. Imports: + +```python +from prediction_batch import PredictionBatch, prediction_cache_key +``` + +Delete the module-level `window_bounds = itemgetter("start", "end")` and its comment (and the now-unused `from operator import itemgetter` if nothing else uses it — check first). + +Class declaration: + +```python +class Prediction(PredictionBatch): +``` + +In `__init__`, after the `PRED_GLOBAL["dict"] = self.__dict__.copy()` line: + +```python + # Deliberately after the PRED_GLOBAL snapshot: a pool worker reconstructs its Prediction + # from that dict and never queues anything, so it has no business carrying a batch. + self.pending_batch = [] + self.batch_threads = 1 +``` + +In `run_prediction`, replace the inline `sim_hash = hash((...))` block with: + +```python + sim_hash = None + if cache and not save: + sim_hash = prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) + cached_result = self.prediction_cache.get(sim_hash) + if cached_result is not None: + # Return cached result + return cached_result +``` + +Then add the four queue entry points, next to their `thread_run_prediction_*` twins: + +```python + def queue_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step): + """Queue a single-scenario prediction, returning a handle - the batch runs on the first get()""" + charge_limit, export_limits = self._prepare_single(charge_limit, export_limits) + return self.enqueue_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, self.prediction_cache_enable) + + def queue_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue a charge-window trial prediction, returning a handle""" + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) + return self.enqueue_prediction(try_charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, self.prediction_cache_enable) + + def queue_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue a charge-window trial prediction that also reports the SoC range across that window. + + Uncached, exactly as the direct path is: the SoC range is not part of the cached result, so a + hit would answer with the wrong shape. + """ + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) + range_window = None if all_n else charge_window[window_n] + return self.enqueue_prediction(try_charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, False, want_range=True, range_window=range_window) + + def queue_run_prediction_export(self, this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue an export-window trial prediction, returning a handle""" + export_window, export_limits = self._prepare_export(this_export_limit, start, window_n, export_window, export_limits, all_n) + return self.enqueue_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, self.prediction_cache_enable) +``` + +- [ ] **Step 5: Switch the launch sites and stop creating the pool** + +In `apps/predbat/plan.py`, replace all four `launch_run_prediction_*` bodies: + +```python + def launch_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step=PREDICT_STEP): + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_single(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step) + + def launch_run_prediction_charge(self, loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_charge(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) + + def launch_run_prediction_charge_min_max(self, loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_charge_min_max(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) + + def launch_run_prediction_export(self, this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record): + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_export(this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record) +``` + +Delete the `wrapped_run_prediction_*` import (line 27 becomes `from prediction import Prediction`) and the `from multiprocessing import Pool, cpu_count` import — both are unused now and Flake8 will fail otherwise. + +Delete the pool creation block (`# Create pool` through the `self.log("Not using threading...")` line) and the LoadML pool-disable block above it, keeping the LoadML status log: + +```python + # Check if LoadML is active - it used to force the process pool off, which no longer exists; + # the kernel's threads are C++ threads with no fork and no NumPy involvement + load_ml_comp = self.components.get_component("load_ml") if self.components else None + if load_ml_comp: + self.log("LoadML is_calculating {}".format(load_ml_comp.is_calculating())) + + # Serial for now - Task 5 wires this to the threads config + self.prediction.batch_threads = 1 +``` + +Place that `batch_threads` assignment immediately after `self.prediction = Prediction(...)` at line 1336. + +- [ ] **Step 6: Run the new tests to verify they pass** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test prediction_batch --test kernel_parity > /tmp/predbat-task4.log 2>&1; grep -nE "ERROR|FAIL|passed|Traceback" /tmp/predbat-task4.log | head -30 +``` + +- [ ] **Step 7: Verify plans are byte-identical — this is the real gate** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-task4-run.log 2>&1; python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json > /tmp/predbat-task4-cmp.log 2>&1; tail -30 /tmp/predbat-task4-cmp.log +``` + +Expected: 20 unchanged, `+0.0000` on metric, cost and all three PV futures. If a scenario moves, the most likely causes in order are: a caller mutating an input between launch and get (the invariant above), the min/max range steps disagreeing with the Python scan, or a cache key built differently on the two paths. + +- [ ] **Step 8: Run the full suite including the slow tests** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all > /tmp/predbat-task4-all.log 2>&1; grep -nE "FAILED|ERROR|Traceback|tests passed|seconds" /tmp/predbat-task4-all.log | tail -25 +``` + +- [ ] **Step 9: Record the serial benchmark** + +Sum `runtime_s` across the 20 scenarios, best of 3 runs. Run-to-run spread is 2-6%, so a single run proves nothing — an earlier single-run measurement in this work produced a bogus 18% "win" that was pure noise. + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && for i in 1 2 3; do python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-bench-serial-$i.log 2>&1; python3 -c "import json;print(round(sum(s['runtime_s'] for s in json.load(open('random_results.json'))['results']), 2))"; done +``` + +Baseline to beat: **31.6s**. + +- [ ] **Step 10: Commit** + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit && git add apps/predbat/prediction_batch.py apps/predbat/prediction.py apps/predbat/plan.py apps/predbat/tests/test_prediction_batch.py && git commit -m "perf(plan): batch the prediction fan-out into one kernel call + +launch_run_prediction_* no longer runs anything: it prepares the trial inputs, queues a job and +returns a handle whose first get() flushes the whole batch through a single pk_run_batch call. Window +start/end arrays are marshalled once per fan-out rather than once per scenario, cache hits and +intra-batch duplicates are resolved in Python first, and anything the kernel refuses falls back to the +Python engine per job. Serial for now. + +20 random scenarios byte-identical. + +Co-Authored-By: Claude Opus 5 (1M context) " +``` + +--- + +### Task 5: Turn on kernel threading + +**Files:** +- Modify: `apps/predbat/plan.py` (threads config → `batch_threads`) +- Modify: `docs/apps-yaml.md:285-297` (`threads` now means kernel threads) +- Test: `apps/predbat/tests/test_prediction_batch.py` + +**Interfaces:** +- Consumes: `Prediction.batch_threads` (Task 4), `run_prediction_kernel_batch`'s `n_threads` (Task 2). +- Produces: nothing new — `batch_threads` is now derived from `args["threads"]`. + +`pk_run_batch` was measured bit-identical at every thread count in the C-level test (Task 2 pins that), so any divergence here is a Python bug, not a race in the kernel. + +- [ ] **Step 1: Write the failing test** + +Add to `apps/predbat/tests/test_prediction_batch.py`: + +```python +def test_batch_threads_do_not_change_results(my_predbat): + """A threaded flush must return exactly what a serial one does, returns True on failure. + + pk_run_batch is pinned bit-identical across thread counts at the C level (kernel_parity), so this + is really checking the Python side: that results are matched back to their own job regardless of + how the kernel split the work. + """ + print("**** Running batch threading tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + socs = [round(my_predbat.soc_max * fraction, 2) for fraction in (0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)] + + reference = None + for n_threads in (1, 2, 8): + prediction.batch_threads = n_threads + prediction.prediction_cache = {} + handles = [prediction.queue_run_prediction_charge(soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for soc in socs] + results = [handle.get() for handle in handles] + if reference is None: + reference = results + elif results != reference: + for index, (got, want) in enumerate(zip(results, reference)): + if got != want: + print("ERROR: job {} at {} threads returned {} expected {}".format(index, n_threads, got, want)) + failed = True + prediction.batch_threads = 1 + + if not failed: + print("Batch threading tests passed - identical results at 1, 2 and 8 threads") + return failed +``` + +and call it from `run_prediction_batch_tests` alongside the others. + +- [ ] **Step 2: Run it and watch it pass already** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test prediction_batch > /tmp/predbat-task5.log 2>&1; grep -nE "ERROR|FAIL|passed|Traceback" /tmp/predbat-task5.log | head -20 +``` + +This one is expected to pass immediately — the plumbing landed in Task 4; the test exists to pin it before the config starts driving it. If it fails, stop: that is a real threading bug and the config must not be wired until it is understood. + +- [ ] **Step 3: Wire the config** + +In `apps/predbat/plan.py`, re-add the import: + +```python +from multiprocessing import cpu_count +``` + +and replace the placeholder from Task 4 with: + +```python + # The kernel spreads one batched fan-out across threads with the GIL released for the whole + # call, so these are real cores - unlike a Python ThreadPool, which peaked at 1.15x on two + # threads and then degraded below serial (perf/threadpool-prototype). + threads = self.get_arg("threads", "auto") + if threads == "auto": + self.prediction.batch_threads = cpu_count() + else: + self.prediction.batch_threads = max(int(threads), 1) + self.log("Prediction batch using {} kernel thread(s)".format(self.prediction.batch_threads)) +``` + +- [ ] **Step 4: Verify plans are byte-identical with threading on** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-task5-run.log 2>&1; python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json > /tmp/predbat-task5-cmp.log 2>&1; tail -30 /tmp/predbat-task5-cmp.log +``` + +Note the benchmark harness may set `threads: 0` (as `annual.py` does deliberately). Check which the run used — grep the run log for `Prediction batch using` — and if it is 1, re-run the benchmark with the template's `threads` raised to `auto` to actually exercise threading before claiming a number. + +- [ ] **Step 5: Benchmark, best of 3** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && for i in 1 2 3; do python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-bench-threaded-$i.log 2>&1; python3 -c "import json;print(round(sum(s['runtime_s'] for s in json.load(open('random_results.json'))['results']), 2))"; done +``` + +Record serial vs threaded against the 31.6s baseline. Remember what the brief predicts: the batch call itself is not faster (0.99x vs a loop of `pk_run`) — the win is the Python-side marshalling plus, now, the threads. Kernel time was already down to ~21.6% of plan time, so Amdahl caps what threading alone can return. + +- [ ] **Step 6: Update the docs** + +`docs/apps-yaml.md`, the `threads` section: + +```markdown +### threads + +If defined sets the number of threads to use during plan calculation, the default is 'auto' which will use the same number of threads as you have CPUs in your system. + +Predbat batches each group of simulations into a single call to the C++ prediction kernel, which then +spreads them across this many threads. Results do not depend on the thread count - the same plan is +produced at any setting - so this only trades CPU for planning time. + +Valid values are: + +- 'auto' - Use the same number of threads as your CPU count +``` + +Keep the rest of the section as it stands, and check whether the list below it still describes reality (e.g. any wording about "0 - no threading" is still correct: 0 means serial). + +```bash +cd /Users/treforsouthwell/predbat/batpred && grep -rn "threads" docs/*.md apps/predbat/*.yaml 2>/dev/null | grep -vi "threshold" | head -20 +``` + +Update anything else that describes threads as worker processes. + +- [ ] **Step 7: Full suite and commit** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all > /tmp/predbat-task5-all.log 2>&1; grep -nE "FAILED|ERROR|Traceback|tests passed" /tmp/predbat-task5-all.log | tail -20 +``` + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit && git add apps/predbat/plan.py apps/predbat/tests/test_prediction_batch.py docs/apps-yaml.md && git commit -m "perf(plan): run each batched fan-out across kernel threads + +args[threads] now sizes the kernel's thread pool rather than a pool of worker processes. The GIL is +released for the whole pk_run_batch call, so unlike a Python ThreadPool these are real cores. + +Identical results at 1, 2 and 8 threads; 20 random scenarios byte-identical. + +Co-Authored-By: Claude Opus 5 (1M context) " +``` + +--- + +### Task 6: Delete the process pool + +**Files:** +- Modify: `apps/predbat/plan.py` (`DummyThread`, pool close/join, unused imports) +- Modify: `apps/predbat/prediction.py` (`wrapped_run_prediction_*`, `PRED_GLOBAL`, `reset_prediction_globals`) +- Modify: `apps/predbat/predbat.py` (`self.pool` lifecycle) +- Modify: `apps/predbat/annual.py:1004`, `apps/predbat/marginal.py:89` (comments referencing `PRED_GLOBAL`) +- Delete: `PHASE_B_BATCH_REFACTOR.md` + +**Interfaces:** +- Consumes: everything from Tasks 1-5. +- Produces: no `self.pool`, no `PRED_GLOBAL`, no `DummyThread`, no `wrapped_run_prediction_*`. + +**Stated consequence:** with the pool gone, a Predbat install where the kernel is unavailable (no binary for the architecture, a stale binary, or `debug_enable` on) plans serially in Python where it used to fan out across processes. The pool was measured at 1.11x on 16 cores with the kernel active; it will be worth more than that without one. This is the brief's call, made explicitly — if that regression is not acceptable, the alternative is to keep the pool solely for the `not kernel_supported()` case, which means keeping `wrapped_run_prediction_*` and `PRED_GLOBAL` alive with it. + +- [ ] **Step 1: Find every reference before deleting anything** + +```bash +cd /Users/treforsouthwell/predbat/batpred && grep -rn "PRED_GLOBAL\|wrapped_run_prediction\|DummyThread\|reset_prediction_globals\|\.pool\b\|apply_async" apps/predbat/ --include="*.py" > /tmp/predbat-pool-refs.txt; cat /tmp/predbat-pool-refs.txt +``` + +Work the list top to bottom. Note `apps/predbat/tests/` may reference these too. + +- [ ] **Step 2: Delete the dead code** + +- `apps/predbat/prediction.py`: remove `PRED_GLOBAL`, `reset_prediction_globals`, all four `wrapped_run_prediction_*`, the `global PRED_GLOBAL` lines in `__init__`, and the `PRED_GLOBAL["dict"] = self.__dict__.copy()` line. `self.pending_batch = []` / `self.batch_threads = 1` stay where they are (the comment above them about the PRED_GLOBAL snapshot no longer applies — delete it). +- `apps/predbat/plan.py`: remove `DummyThread` and its preamble comment, and the pool `close()`/`join()` blocks at ~1621-1628. Check whether `import time` is still used elsewhere in the file before removing it. +- `apps/predbat/predbat.py`: remove the `self.pool` attribute and its terminate/close/join blocks (lines ~283-288, 320, 1180-1188, 1612, 1735-1743). +- `apps/predbat/annual.py`: the `predbat.args["threads"] = 0` line stays (it now means serial batching, which is still what a per-day annual run wants), but rewrite the comment — the PRED_GLOBAL/spawn-safety reasoning it gives is gone. Something like: "The annual tool plans hundreds of small, fast days per run, where splitting each fan-out across kernel threads costs more in thread setup than it returns." +- `apps/predbat/marginal.py:89`: drop the "this updates PRED_GLOBAL which is safe since we run synchronously" comment; the remaining sentence about not needing 10% extra load stays. + +- [ ] **Step 3: Verify nothing references the removed names** + +```bash +cd /Users/treforsouthwell/predbat/batpred && grep -rn "PRED_GLOBAL\|wrapped_run_prediction\|DummyThread\|reset_prediction_globals\|apply_async\|self\.pool" apps/predbat/ --include="*.py" +``` + +Expected: no output. + +- [ ] **Step 4: Full suite plus the parity gate** + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-task6-run.log 2>&1; python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json > /tmp/predbat-task6-cmp.log 2>&1; tail -30 /tmp/predbat-task6-cmp.log +``` + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all > /tmp/predbat-task6-all.log 2>&1; grep -nE "FAILED|ERROR|Traceback|tests passed|seconds" /tmp/predbat-task6-all.log | tail -25 +``` + +`annual_integration` is the one most likely to notice this task — it explicitly sets `threads: 0` and its comment about the pool is what changed. Check its timing in the log against the ~34s the brief records. + +- [ ] **Step 5: Delete the brief** + +```bash +cd /Users/treforsouthwell/predbat/batpred && git rm PHASE_B_BATCH_REFACTOR.md +``` + +- [ ] **Step 6: Commit** + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit && git add -A apps/predbat docs && git commit -m "refactor(plan): remove the prediction process pool + +Nothing has launched work into it since the fan-out started batching, so PRED_GLOBAL, the four +wrapped_run_prediction_* trampolines, DummyThread and the pool lifecycle all go with it. The pool was +measured at 1.11x on 16 cores, with the parent's per-call pickling as the serial bottleneck. + +20 random scenarios byte-identical. + +Co-Authored-By: Claude Opus 5 (1M context) " +``` + +--- + +## Final verification before the branch is offered for merge + +Run all four gates from the brief, in this order, and paste the actual output rather than summarising it: + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && python3 ../apps/predbat/unit_test.py --random-run --random-template cases/predbat_debug_agile1.yaml --random-scenarios cases/random_scenarios.yaml > /tmp/predbat-final-run.log 2>&1; python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json > /tmp/predbat-final-cmp.log 2>&1; tail -30 /tmp/predbat-final-cmp.log +``` + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all --test kernel_parity --test prediction_batch > /tmp/predbat-final-parity.log 2>&1; grep -nE "ERROR|FAILED|passed" /tmp/predbat-final-parity.log | tail -20 +``` + +```bash +cd /Users/treforsouthwell/predbat/batpred/coverage && source setup.csh && ./run_all > /tmp/predbat-final-all.log 2>&1; grep -nE "FAILED|ERROR|Traceback|tests passed|seconds" /tmp/predbat-final-all.log | tail -25 +``` + +```bash +cd /Users/treforsouthwell/predbat/batpred && ./run_pre_commit +``` + +Required: 20 scenarios unchanged with `+0.0000` on metric, cost and all three PV futures; kernel parity green; full suite green including the slow tests; pre-commit clean (re-run and re-stage after the cspell dictionary auto-sorts). + +Then report, best of 3 each: serial batch vs threaded batch vs the 31.6s pre-Phase-B baseline. + +## Notes for whoever picks this up + +- **`PR #4536` (`perf/window-bounds-cache`) is in flight and independent**, worth -21% on its own. Batching partly subsumes it — a batch ships window bounds once per fan-out rather than per call — but the `sim_hash` half still matters, and `prediction_cache_key()` in `prediction_batch.py` is exactly where that half would land. If both branches merge, re-profile before assuming what is left. +- **`round_py` is poison in any hot loop** — `snprintf`+`strtod`, ~96ns, serialising on libc's global locale, measured 17x degradation at 8 threads. Two calls remain in the kernel (`iboost_next`, `car_soc_next`), both once per run. Do not add a third. +- **Any new test that calls `calculate_plan` must not use the shared `my_predbat` fixture** — it arrives carrying whatever earlier tests left on it and `calculate_plan` raises. Follow `run_annual_integration_isolated` in `unit_test.py`: take a fresh instance from `create_predbat()` and load a debug YAML. +- **Do not re-litigate the dead ends**: Python `ThreadPool` (1.15x peak, then below serial), the process pool itself (1.11x on 16 cores), and expecting `pk_run_batch` to beat a loop of `pk_run` on its own (0.99x). All three were measured on this work. From 76473587bf20036a36be05ff03a8a0b6adfb6988 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 18:57:38 +0100 Subject: [PATCH 07/24] fix(prediction): build the export trial window privately instead of mutating the caller's The trial start was written straight into the caller's window dict, which was only safe because each pool worker mutated its own unpickled copy. A batched fan-out shares one window list across every job in the batch, so this has to be local. Ported from perf/threadpool-prototype. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction.py | 23 ++++-- apps/predbat/tests/test_prediction_batch.py | 82 +++++++++++++++++++++ apps/predbat/unit_test.py | 2 + 3 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 apps/predbat/tests/test_prediction_batch.py diff --git a/apps/predbat/prediction.py b/apps/predbat/prediction.py index 2cc7053a2..d018eb8b1 100644 --- a/apps/predbat/prediction.py +++ b/apps/predbat/prediction.py @@ -355,11 +355,15 @@ def thread_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, max_soc, ) - def thread_run_prediction_export(self, this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """ - Run prediction in a thread + def _prepare_export(self, this_export_limit, start, window_n, export_window, export_limits, all_n): + """Build the trial export limits and window list - shared by thread_run_prediction_export and the batch path. + + The trial start is applied to a private copy of the window rather than written into the + caller's list: with a process pool each worker mutated its own unpickled copy, but a batched + fan-out shares one list across every job in the batch, so an in-place write would corrupt the + other trials of the same window. Only ["end"] is ever read back by the caller + (optimise_export), so nothing depends on the write being visible. """ - # Store try value into the window export_limits = export_limits.copy() if all_n: @@ -370,7 +374,16 @@ def thread_run_prediction_export(self, this_export_limit, start, window_n, charg # Adjust start window = export_window[window_n] start = min(start, window["end"] - 5) - export_window[window_n]["start"] = start + export_window = list(export_window) + export_window[window_n] = dict(window, start=start) + + return export_window, export_limits + + def thread_run_prediction_export(self, this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """ + Run prediction in a thread + """ + export_window, export_limits = self._prepare_export(this_export_limit, start, window_n, export_window, export_limits, all_n) ( metricmid, diff --git a/apps/predbat/tests/test_prediction_batch.py b/apps/predbat/tests/test_prediction_batch.py new file mode 100644 index 000000000..059317aac --- /dev/null +++ b/apps/predbat/tests/test_prediction_batch.py @@ -0,0 +1,82 @@ +# ----------------------------------------------------------------------------- +# Predbat Home Battery System +# Copyright Trefor Southwell 2026 - All Rights Reserved +# This application maybe used for personal use only and not for commercial use +# ----------------------------------------------------------------------------- +# fmt off +# pylint: disable=consider-using-f-string +# pylint: disable=line-too-long + +"""Tests for the batched prediction fan-out. + +launch_run_prediction_* no longer runs anything: it queues a job on the Prediction and returns a +handle whose first get() flushes the whole batch through one pk_run_batch call. These tests pin the +two things that makes conditional - that a queued job returns exactly what the direct +thread_run_prediction_* path returns, and that a job the kernel cannot take still runs. +""" + + +from prediction import Prediction + + +def make_export_windows(minutes_now): + """Build a small deterministic export window layout for the trial-input tests""" + return [ + {"start": minutes_now + 60, "end": minutes_now + 120, "average": 15.0}, + {"start": minutes_now + 180, "end": minutes_now + 240, "average": 20.0}, + ] + + +def test_export_trial_does_not_mutate_caller_window(my_predbat): + """The export trial must build its own window list, returns True on failure. + + It used to write the trial start straight into the caller's window dict, which was only safe + because each pool worker mutated its own unpickled copy. A batched fan-out holds one shared list + across every job in the batch, so an in-place write would corrupt every other trial of the same + window. + """ + print("**** Running export trial input tests ****") + failed = False + minutes_now = my_predbat.minutes_now + export_window = make_export_windows(minutes_now) + export_limits = [100.0, 100.0] + original = [dict(window) for window in export_window] + + prediction = Prediction(my_predbat, {}, {}, {}, {}) + trial_window, trial_limits = prediction._prepare_export(5.0, minutes_now + 90, 0, export_window, export_limits, None) + + if export_window != original: + print("ERROR: _prepare_export mutated the caller's export window: {} vs {}".format(export_window, original)) + failed = True + if export_limits != [100.0, 100.0]: + print("ERROR: _prepare_export mutated the caller's export limits: {}".format(export_limits)) + failed = True + if trial_window[0]["start"] != minutes_now + 90: + print("ERROR: trial window start not applied, got {}".format(trial_window[0]["start"])) + failed = True + if trial_window[1] is not export_window[1]: + print("ERROR: untouched windows should be shared with the caller's list, not copied") + failed = True + if trial_limits[0] != 5.0: + print("ERROR: trial export limit not applied, got {}".format(trial_limits[0])) + failed = True + + # The trial start is clamped to at least 5 minutes before the window end + trial_window, _ = prediction._prepare_export(5.0, minutes_now + 200, 0, export_window, export_limits, None) + if trial_window[0]["start"] != minutes_now + 115: + print("ERROR: trial window start not clamped to end-5, got {}".format(trial_window[0]["start"])) + failed = True + + if not failed: + print("Export trial input tests passed") + return failed + + +def run_prediction_batch_tests(my_predbat): + """Run every batched prediction test, returns True on failure""" + failed = test_export_trial_does_not_mutate_caller_window(my_predbat) + if failed: + print("**** Prediction batch tests FAILED ****") + else: + print("**** Prediction batch tests passed ****") + return failed diff --git a/apps/predbat/unit_test.py b/apps/predbat/unit_test.py index 16fac4fd8..03973c7f5 100644 --- a/apps/predbat/unit_test.py +++ b/apps/predbat/unit_test.py @@ -23,6 +23,7 @@ from tests.test_model import run_model_tests from tests.test_predict_pv_power import run_predict_pv_power_tests from tests.test_kernel_parity import run_kernel_parity_tests, run_model_kernel_tests +from tests.test_prediction_batch import run_prediction_batch_tests from tests.test_execute import run_execute_tests from tests.test_load_car_energy import test_load_car_energy_warns_when_configured_entity_has_no_data from tests.test_octopus_slots import run_load_octopus_slots_tests @@ -297,6 +298,7 @@ def main(): ("predict_pv_power", run_predict_pv_power_tests, "predict_pv_power plan-interval scaling tests", False), ("model_kernel", run_model_kernel_tests, "Model tests run with the C++ prediction kernel enabled", False), ("kernel_parity", run_kernel_parity_tests, "C++ prediction kernel vs Python engine parity tests", False), + ("prediction_batch", run_prediction_batch_tests, "Batched prediction fan-out tests", False), ("inverter", run_inverter_tests, "Inverter tests", False), ("execute", run_execute_tests, "Execute tests", False), ("load_car_energy", test_load_car_energy_warns_when_configured_entity_has_no_data, "car_charging_energy configured-but-empty warning tests (#4458 follow-up)", False), From 877cc8b9fde36bd00bdc492bf97737e7d895b495 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 19:03:52 +0100 Subject: [PATCH 08/24] chore: green the quality gate on the batching branch The hand-off notes landed without passing cspell or markdownlint, so pre-commit has been red on this branch since. Adds the five technical words the notes use and tags their two code fences. Co-Authored-By: Claude Opus 5 (1M context) --- .cspell/custom-dictionary-workspace.txt | 5 +++++ PHASE_B_BATCH_REFACTOR.md | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.cspell/custom-dictionary-workspace.txt b/.cspell/custom-dictionary-workspace.txt index ee6ebdf9c..6ef384d4b 100644 --- a/.cspell/custom-dictionary-workspace.txt +++ b/.cspell/custom-dictionary-workspace.txt @@ -51,6 +51,7 @@ byok cadata calib Cantarell +CDLL cdn Cerbo cexxxx @@ -77,6 +78,7 @@ corruptplans cprofile creds crosscharge +ctypes customauthorizer customisation Customise @@ -491,6 +493,7 @@ temperation Teslemetry testname thirdparty +threadpool timea timeb timec @@ -522,6 +525,8 @@ unconfigured undiscounted unnormalised unparseable +unpickled +unpushed unsmoothed unstaged urlsafe diff --git a/PHASE_B_BATCH_REFACTOR.md b/PHASE_B_BATCH_REFACTOR.md index 35dd7dfb6..7d98291cf 100644 --- a/PHASE_B_BATCH_REFACTOR.md +++ b/PHASE_B_BATCH_REFACTOR.md @@ -23,7 +23,7 @@ three PV futures, `kernel_parity` green, full suite green including slow tests ( Measured on `cases/random_scenarios.yaml` scenario 0 (the benchmark scenario), `threads=0`: -``` +```text calculate_plan 2418.4 ms -> 1758.5 ms -27% C++ pk_run 1056.5 ms -> 380.5 ms Python 1361.9 ms -> 1378.0 ms unchanged, as expected @@ -71,7 +71,7 @@ to change at all** — only what `launch_*` returns and when the work actually h Batch sizes this produces (scenario 0, from the profile): -``` +```text launch_run_prediction_charge 10,698 launch_run_prediction_export 5,436 launch_run_prediction_single 4,752 @@ -79,6 +79,7 @@ launch_run_prediction_charge_min_max 3,294 ------ 24,180 launches, ~19,209 reaching the kernel ``` + `optimise_charge_limit_price_threads` fans out ~1176 at a time (392 candidates x 3 PV scenarios), `optimise_charge_limit` ~900, `optimise_export` ~628. Those are the batches. @@ -140,10 +141,12 @@ A per-job `status` is returned precisely so one malformed scenario cannot discar 1. **`thread_run_prediction_export` used to mutate the caller's window dict** (`export_window[n]["start"] = start`). That was only safe because each pool worker mutated its own unpickled copy. Any shared-memory parallelism needs it local. The fix is on branch `perf/threadpool-prototype`: + ```python export_window = list(export_window) export_window[window_n] = dict(window, start=start) ``` + Only `["end"]` is ever read back by `optimise_export`, so nothing depends on the write being visible. **Port this across.** From 30d025e203a262bd021e7f6b05f857d13ce8297b Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 19:12:08 +0100 Subject: [PATCH 09/24] feat(kernel): marshal a whole fan-out into one pk_run_batch call Adds BatchJob, run_prediction_kernel_batch and the shared result assembly, and gives pk_run_batch's ctypes binding the n_threads argument it was missing. Window start/end arrays are marshalled once per distinct window list rather than once per job, which is where the batching win comes from. Also adds Prediction.scan_soc_range and routes thread_run_prediction_charge_min_max through it so the scan logic is not duplicated ahead of the batch runner landing in a later task. Bit-identical to a loop of pk_run across 60 scenarios at 1, 2, 4 and 8 threads. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction.py | 29 +++- apps/predbat/prediction_kernel.py | 201 ++++++++++++++++++----- apps/predbat/tests/test_kernel_parity.py | 113 +++++++++++++ 3 files changed, 296 insertions(+), 47 deletions(-) diff --git a/apps/predbat/prediction.py b/apps/predbat/prediction.py index d018eb8b1..91c7bfb83 100644 --- a/apps/predbat/prediction.py +++ b/apps/predbat/prediction.py @@ -295,6 +295,25 @@ def thread_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_w final_carbon_g, ) + def scan_soc_range(self, predict_soc, window): + """Return the (min, max) SoC across a charge window - shared by the direct and batch min/max paths. + + The kernel computes the same range inline (see PkBatchJob.soc_range_start_step), so this is + only reached when a job falls back to the Python engine; the two must agree exactly, including + the clamping that collapses an empty range to a single value rather than leaving min above max. + """ + min_soc = self.soc_max + max_soc = 0 + predict_minute_start = max(int((window["start"] - self.minutes_now) / 5) * 5, 0) + predict_minute_end = int((window["end"] - self.minutes_now) / 5) * 5 + for minute in range(predict_minute_start, predict_minute_end + 5, 5): + if minute in predict_soc: + min_soc = min(predict_soc[minute], min_soc) + max_soc = max(predict_soc[minute], max_soc) + max_soc = max(max_soc, min_soc) + min_soc = min(min_soc, max_soc) + return min_soc, max_soc + def thread_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): """ Run prediction in a thread @@ -329,15 +348,7 @@ def thread_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, min_soc = self.soc_max max_soc = 0 if not all_n: - window = charge_window[window_n] - predict_minute_start = max(int((window["start"] - self.minutes_now) / 5) * 5, 0) - predict_minute_end = int((window["end"] - self.minutes_now) / 5) * 5 - for minute in range(predict_minute_start, predict_minute_end + 5, 5): - if minute in predict_soc: - min_soc = min(predict_soc[minute], min_soc) - max_soc = max(predict_soc[minute], max_soc) - max_soc = max(max_soc, min_soc) - min_soc = min(min_soc, max_soc) + min_soc, max_soc = self.scan_soc_range(predict_soc, charge_window[window_n]) return ( cost, diff --git a/apps/predbat/prediction_kernel.py b/apps/predbat/prediction_kernel.py index 7d90317cd..d90005a61 100644 --- a/apps/predbat/prediction_kernel.py +++ b/apps/predbat/prediction_kernel.py @@ -212,6 +212,33 @@ class PkBatchResult(ctypes.Structure): ] +class BatchJob: + """One queued prediction: its trial inputs, how the result should be shaped, and the result itself. + + run_prediction_kernel_batch reads only the input fields and the SoC range steps. sim_hash, + want_range, range_window and result belong to the batch runner in prediction_batch.py, which is + the only thing that creates these; they live here so the ctypes layer can be tested on its own. + """ + + __slots__ = ("charge_limit", "charge_window", "export_window", "export_limits", "pv_scenario", "end_record", "step", "soc_range_start_step", "soc_range_end_step", "sim_hash", "want_range", "range_window", "result") + + def __init__(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, soc_range_start_step=-1, soc_range_end_step=-1, sim_hash=None, want_range=False, range_window=None): + """Record one job's trial inputs; result stays None until the batch is flushed""" + self.charge_limit = charge_limit + self.charge_window = charge_window + self.export_window = export_window + self.export_limits = export_limits + self.pv_scenario = pv_scenario + self.end_record = end_record + self.step = step + self.soc_range_start_step = soc_range_start_step + self.soc_range_end_step = soc_range_end_step + self.sim_hash = sim_hash + self.want_range = want_range + self.range_window = range_window + self.result = None + + def kernel_library_candidates(): """Return the ordered list of shared library paths to try loading. @@ -286,7 +313,9 @@ def load_kernel(log=None): lib.pk_run.argtypes = [ctypes.c_int64, ctypes.POINTER(PkScenario), ctypes.POINTER(PkResult)] try: lib.pk_run_batch.restype = ctypes.c_int32 - lib.pk_run_batch.argtypes = [ctypes.c_int64, ctypes.POINTER(PkBatchJob), ctypes.c_int32, ctypes.POINTER(PkBatchResult)] + # The trailing c_int32 is n_threads - pk_run_batch takes five arguments, and ctypes + # will happily pass a fourth-and-a-bit if the binding says otherwise + lib.pk_run_batch.argtypes = [ctypes.c_int64, ctypes.POINTER(PkBatchJob), ctypes.c_int32, ctypes.POINTER(PkBatchResult), ctypes.c_int32] KERNEL_HAS_BATCH = True except AttributeError: KERNEL_HAS_BATCH = False @@ -535,6 +564,136 @@ def kernel_supported(pred, save, step): return not save and not pred.debug_enable and getattr(pred, "kernel_handle", 0) != 0 +def kernel_result_tuple(pred, result, predict_soc): + """Assemble the 17-field Prediction.run_prediction() result tuple from a PkResult. + + Shared by the single-scenario and batch paths - mirrors prediction.py:626-628, 1266-1284. + """ + car_charging_soc_next = pred.car_charging_soc_next[:] + if result.car_soc_next_valid: + for car_n in range(pred.num_cars): + car_charging_soc_next[car_n] = result.car_soc_next[car_n] + + iboost_next = result.iboost_next if pred.iboost_enable else pred.iboost_next + + return ( + round(result.final_metric, 4), + round(result.import_kwh_battery, 4), + round(result.import_kwh_house, 4), + round(result.export_kwh, 4), + round(result.soc_min, 4), + round(result.final_soc, 4), + result.soc_min_minute, + round(result.battery_cycle, 4), + round(result.metric_keep, 4), + round(result.final_iboost, 4), + round(result.final_carbon_g, 4), + predict_soc, + car_charging_soc_next, + iboost_next, + bool(result.iboost_running), + bool(result.iboost_running_solar), + bool(result.iboost_running_full), + ) + + +def reset_kernel_run_state(pred): + """Clear the per-run state attributes exactly as the Python engine does - prediction.py:414-422 + + Non-save runs never populate these, so they simply stay empty/False; a kernel run has to leave + the Prediction in the same state a Python run would. + """ + pred.predict_soc_best = {} + pred.predict_metric_best = {} + pred.predict_iboost_best = {} + pred.predict_carbon_best = {} + pred.predict_clipped_best = {} + pred.iboost_running = False + pred.iboost_running_solar = False + pred.iboost_running_full = False + + +def run_prediction_kernel_batch(pred, jobs, n_threads=1): + """Run a whole fan-out of prediction scenarios through the kernel in one pk_run_batch call. + + Returns a list of (result_tuple, soc_range_min, soc_range_max) in job order, where result_tuple + is the same 17-field tuple Prediction.run_prediction() returns, or None for a job the kernel + refused - the caller re-runs those through the Python engine. Returns None when the batch could + not be run at all (no kernel, no batch entry point, or a non-zero return code). + + Whether the kernel is allowed to answer at all is the caller's decision, not this function's: + kernel_supported() also refuses debug and saving runs, and flush_batch checks it before getting + here. + + Batched jobs never materialise the per-minute SoC series: their callers all discard it, and one + buffer per job would be ~84MB on a large batch. The one thing a caller does want from it - the + SoC range across a charge window - the kernel tracks inline over + [soc_range_start_step, soc_range_end_step] instead. + """ + lib = KERNEL_LIB + if not lib or not KERNEL_HAS_BATCH or not getattr(pred, "kernel_handle", 0): + return None + + n_jobs = len(jobs) + job_array = (PkBatchJob * n_jobs)() + result_array = (PkBatchResult * n_jobs)() + # Every ctypes buffer behind a pointer field has to outlive the call. Structures reached through + # an array index do not keep their own _objects, so the buffers are held here rather than relying + # on ctypes' keepalive doing the right thing through the array. + buffers = [] + # A fan-out reuses the same window lists across most of its jobs, so their start/end arrays are + # marshalled once per distinct list instead of once per job - that is the bulk of the batching + # win. Keyed on identity, with the list retained so an id() cannot be recycled mid-batch. This + # relies on no caller mutating a window list between enqueue and flush (see prediction_batch.py). + window_cache = {} + + def window_arrays(windows): + """Marshal a window list's start/end arrays, reusing an earlier job's arrays where possible""" + entry = window_cache.get(id(windows)) + if entry is None: + entry = (int32_array([window["start"] for window in windows]), int32_array([window["end"] for window in windows]), windows) + window_cache[id(windows)] = entry + return entry + + for index, job in enumerate(jobs): + charge_start, charge_end, _ = window_arrays(job.charge_window) + export_start, export_end, _ = window_arrays(job.export_window) + charge_limit = double_array(job.charge_limit) + export_limits = double_array(job.export_limits) + buffers.append((charge_limit, export_limits)) + + pk_job = job_array[index] + pk_job.charge_limit = charge_limit + pk_job.charge_start = charge_start + pk_job.charge_end = charge_end + pk_job.export_limits = export_limits + pk_job.export_start = export_start + pk_job.export_end = export_end + pk_job.soc_out = None + pk_job.n_charge = len(job.charge_window) + pk_job.n_export = len(job.export_window) + pk_job.pv_scenario = int(job.pv_scenario) + pk_job.end_record = job.end_record + pk_job.step = PREDICT_STEP # the caller's step is ignored - see run_prediction_kernel + pk_job.soc_range_start_step = job.soc_range_start_step + pk_job.soc_range_end_step = job.soc_range_end_step + + return_code = lib.pk_run_batch(pred.kernel_handle, job_array, n_jobs, result_array, max(int(n_threads), 1)) + if return_code != 0: + return None + + reset_kernel_run_state(pred) + + results = [] + for index in range(n_jobs): + batch_result = result_array[index] + if batch_result.status != 0: + results.append((None, 0.0, 0.0)) + continue + results.append((kernel_result_tuple(pred, batch_result.result, {}), batch_result.soc_range_min, batch_result.soc_range_max)) + return results + + def run_prediction_kernel(pred, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, cache): """Run one prediction scenario through the C++ kernel. @@ -582,18 +741,9 @@ def run_prediction_kernel(pred, charge_limit, charge_window, export_window, expo if return_code != 0: return None - # Reset the per-run state attributes exactly as the Python engine does - prediction.py:414-422 - # (non-save runs never populate these, so they remain empty/False) - pred.predict_soc_best = {} - pred.predict_metric_best = {} - pred.predict_iboost_best = {} - pred.predict_carbon_best = {} - pred.predict_clipped_best = {} - pred.iboost_running = False - pred.iboost_running_solar = False - pred.iboost_running_full = False + reset_kernel_run_state(pred) - # Assemble the same return value as the Python engine - prediction.py:626-628, 1266-1284 + # Assemble the same return value as the Python engine predict_soc = {} if not cache: # Indexed loop, not dict(zip(range(...), soc_out)): iterating a ctypes array boxes each double @@ -601,29 +751,4 @@ def run_prediction_kernel(pred, charge_limit, charge_window, export_window, expo for k in range(n_steps): predict_soc[k * PREDICT_STEP] = soc_out[k] - car_charging_soc_next = pred.car_charging_soc_next[:] - if result.car_soc_next_valid: - for car_n in range(pred.num_cars): - car_charging_soc_next[car_n] = result.car_soc_next[car_n] - - iboost_next = result.iboost_next if pred.iboost_enable else pred.iboost_next - - return ( - round(result.final_metric, 4), - round(result.import_kwh_battery, 4), - round(result.import_kwh_house, 4), - round(result.export_kwh, 4), - round(result.soc_min, 4), - round(result.final_soc, 4), - result.soc_min_minute, - round(result.battery_cycle, 4), - round(result.metric_keep, 4), - round(result.final_iboost, 4), - round(result.final_carbon_g, 4), - predict_soc, - car_charging_soc_next, - iboost_next, - bool(result.iboost_running), - bool(result.iboost_running_solar), - bool(result.iboost_running_full), - ) + return kernel_result_tuple(pred, result, predict_soc) diff --git a/apps/predbat/tests/test_kernel_parity.py b/apps/predbat/tests/test_kernel_parity.py index 38bd9dbda..666191862 100644 --- a/apps/predbat/tests/test_kernel_parity.py +++ b/apps/predbat/tests/test_kernel_parity.py @@ -849,6 +849,117 @@ def run_clipping_parity_tests(my_predbat, count=250): return failed +def build_batch_jobs(my_predbat, rng, count): + """Build a list of BatchJob scenarios plus the Prediction they run against""" + apply_random_scenario(my_predbat, rng) + pv_step, pv10_step, load_step, load10_step = make_step_data(my_predbat, rng) + my_predbat.prediction_kernel_enable = True + prediction = Prediction(my_predbat, pv_step, pv10_step, load_step, load10_step) + prediction.kernel_handle = create_kernel_context(prediction) + + charge_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) + export_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) + end_record = my_predbat.forecast_minutes + + jobs = [] + for index in range(count): + charge_limit = [round(rng.uniform(0, my_predbat.soc_max), 2) for _ in charge_window] + export_limits = [rng.choice([100.0, 99.0, 0.0, round(rng.uniform(1, 99), 1)]) for _ in export_window] + pv_scenario = rng.choice([PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90]) + # Every third job asks for the SoC range over a charge window, as the min/max fan-out does + range_window = charge_window[index % len(charge_window)] if (index % 3) == 0 else None + start_step = -1 + end_step = -1 + if range_window is not None: + start_step = max(int((range_window["start"] - my_predbat.minutes_now) / 5) * 5, 0) // 5 + end_step = int((range_window["end"] - my_predbat.minutes_now) / 5) * 5 // 5 + jobs.append( + prediction_kernel.BatchJob( + charge_limit, + charge_window, + export_window, + export_limits, + pv_scenario, + end_record, + 5, + soc_range_start_step=start_step, + soc_range_end_step=end_step, + want_range=range_window is not None, + range_window=range_window, + ) + ) + return prediction, jobs + + +def run_batch_parity_tests(my_predbat, count=60): + """Check pk_run_batch matches a loop of pk_run exactly, at every thread count, returns True on failure. + + The batch path is the only one Python will use after this refactor, and it is the only one that + can run scenarios concurrently, so it is checked against the single-scenario path it replaces + rather than against the Python engine (which run_random_sweep_tests already pins pk_run against). + Results must be bit-identical, not merely close: the whole point of the fan-out is that plans do + not change. + """ + print("**** Running kernel batch parity tests ****") + if not prediction_kernel.KERNEL_HAS_BATCH: + print("SKIP: kernel does not expose pk_run_batch") + return False + + failed = False + prediction, jobs = build_batch_jobs(my_predbat, random.Random(4321), count) + if not prediction.kernel_handle: + print("ERROR: batch parity kernel context creation failed") + return True + + # Reference: one pk_run per scenario, with the SoC series materialised so the range can be + # scanned in Python exactly as thread_run_prediction_charge_min_max does + reference = [] + for job in jobs: + single = run_prediction_kernel(prediction, job.charge_limit, job.charge_window, job.export_window, job.export_limits, job.pv_scenario, job.end_record, 5, False) + if single is None: + print("ERROR: reference pk_run failed") + return True + if job.range_window is None: + soc_range = (prediction.soc_max, 0) + else: + soc_range = prediction.scan_soc_range(single[11], job.range_window) + reference.append((single, soc_range)) + + for n_threads in (1, 2, 4, 8): + batched = prediction_kernel.run_prediction_kernel_batch(prediction, jobs, n_threads) + if batched is None: + print("ERROR: pk_run_batch failed at {} threads".format(n_threads)) + return True + if len(batched) != len(jobs): + print("ERROR: pk_run_batch returned {} results for {} jobs".format(len(batched), len(jobs))) + return True + for index, (result_tuple, soc_range_min, soc_range_max) in enumerate(batched): + single, (expect_min, expect_max) = reference[index] + if result_tuple is None: + print("ERROR: job {} reported a non-zero status at {} threads".format(index, n_threads)) + failed = True + continue + for field, name in enumerate(RESULT_NAMES): + if result_tuple[field] != single[field]: + print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) + failed = True + # The batch never materialises the SoC series - that is what makes it affordable + if result_tuple[11] != {}: + print("ERROR: job {} returned a SoC series from the batch path".format(index)) + failed = True + for field, name in [(12, "car_charging_soc_next"), (13, "iboost_next"), (14, "iboost_running"), (15, "iboost_running_solar"), (16, "iboost_running_full")]: + if result_tuple[field] != single[field]: + print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) + failed = True + if soc_range_min != expect_min or soc_range_max != expect_max: + print("ERROR: job {} at {} threads SoC range {} {} expected {} {}".format(index, n_threads, soc_range_min, soc_range_max, expect_min, expect_max)) + failed = True + + if not failed: + print("Batch parity: {} scenarios bit-identical to pk_run at 1, 2, 4 and 8 threads".format(count)) + return failed + + def kernel_available(): """Ensure the kernel library is built and loaded, returns (available, required_failure)""" if not ensure_kernel_built(): @@ -927,6 +1038,8 @@ def run_kernel_parity_tests(my_predbat): failed |= run_random_sweep_tests(my_predbat) if not failed: failed |= run_clipping_parity_tests(my_predbat) + if not failed: + failed |= run_batch_parity_tests(my_predbat) finally: restore_scenario_state(my_predbat, state) From 5044b5828ec575504f865254fd17572c014f52a1 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 19:26:57 +0100 Subject: [PATCH 10/24] test(kernel): pin the pk_run_batch argtypes and the window memo's cache key Closes two review findings on the batch entry point: the argtypes fix had no regression test (ctypes silently accepts extra call arguments, and a garbage n_threads only changes work splitting, not results, so the bug was invisible to the batch parity sweep), and the window-array memo was only ever exercised with one shared list per side, never with genuinely distinct lists in the same batch. Adds a direct argtypes assertion to run_marshalling_tests, and a new run_batch_window_variant_tests that cycles jobs across several distinct charge/export window lists and checks the batch against the same per-scenario pk_run reference. Extracted build_batch_reference and check_batch_results out of run_batch_parity_tests so the new test reuses them instead of duplicating the comparison, which also brings run_batch_parity_tests back under the repo's flake8 complexity limit. Also rewords a comment on the buffers keepalive list that overstated why it's needed (ctypes' own container keepalive already covers it; the list is belt-and-braces, not load-bearing) - comment only, no code change. Both new assertions verified to actually catch their target bugs via temporary mutation, reverted before committing. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction_kernel.py | 6 +- apps/predbat/tests/test_kernel_parity.py | 170 +++++++++++++++++------ 2 files changed, 131 insertions(+), 45 deletions(-) diff --git a/apps/predbat/prediction_kernel.py b/apps/predbat/prediction_kernel.py index d90005a61..5ecc7755e 100644 --- a/apps/predbat/prediction_kernel.py +++ b/apps/predbat/prediction_kernel.py @@ -637,9 +637,9 @@ def run_prediction_kernel_batch(pred, jobs, n_threads=1): n_jobs = len(jobs) job_array = (PkBatchJob * n_jobs)() result_array = (PkBatchResult * n_jobs)() - # Every ctypes buffer behind a pointer field has to outlive the call. Structures reached through - # an array index do not keep their own _objects, so the buffers are held here rather than relying - # on ctypes' keepalive doing the right thing through the array. + # Every ctypes buffer behind a pointer field has to outlive the call. ctypes' own keepalive already + # covers this (b_base walks up to job_array._objects), so this list is belt-and-braces: the limit + # arrays are held explicitly here rather than relying on ctypes' container keepalive. buffers = [] # A fan-out reuses the same window lists across most of its jobs, so their start/end arrays are # marshalled once per distinct list instead of once per job - that is the bulk of the batching diff --git a/apps/predbat/tests/test_kernel_parity.py b/apps/predbat/tests/test_kernel_parity.py index 666191862..919b31fd0 100644 --- a/apps/predbat/tests/test_kernel_parity.py +++ b/apps/predbat/tests/test_kernel_parity.py @@ -423,6 +423,19 @@ def run_marshalling_tests(): print("ERROR: {}([]) should be empty, got length {}".format(name, len(empty))) failed = True + # pk_run_batch's binding used to be missing its trailing n_threads entry in argtypes. That bug is invisible + # to the batch parity test: ctypes silently accepts more call arguments than argtypes declares, and + # a garbage thread count only changes how pk_run_batch splits work across threads - the results are + # thread-count-independent by design. Only asserting the binding itself catches a regression here. + if prediction_kernel.KERNEL_HAS_BATCH: + expected_argtypes = (ctypes.c_int64, ctypes.POINTER(prediction_kernel.PkBatchJob), ctypes.c_int32, ctypes.POINTER(prediction_kernel.PkBatchResult), ctypes.c_int32) + actual_argtypes = tuple(prediction_kernel.KERNEL_LIB.pk_run_batch.argtypes) + if actual_argtypes != expected_argtypes: + print("ERROR: pk_run_batch.argtypes is {} but the C++ signature (handle, jobs, n_jobs, results, n_threads) needs {}".format(actual_argtypes, expected_argtypes)) + failed = True + else: + print("SKIP: pk_run_batch argtypes check - kernel does not expose pk_run_batch") + if not failed: print("PASS") return failed @@ -849,20 +862,29 @@ def run_clipping_parity_tests(my_predbat, count=250): return failed -def build_batch_jobs(my_predbat, rng, count): - """Build a list of BatchJob scenarios plus the Prediction they run against""" +def build_batch_jobs(my_predbat, rng, count, window_variants=1): + """Build a list of BatchJob scenarios plus the Prediction they run against. + + window_variants controls how many distinct charge/export window lists the batch draws from, cycled + by job index (job N uses variant N % window_variants). The default of 1 shares a single list across + every job, as the real min/max fan-out does when it scans one window at a time. A caller wanting + per-job window lists - to exercise run_prediction_kernel_batch's identity-keyed window memo, whose + cache key is id(windows), not its content - passes a larger value. + """ apply_random_scenario(my_predbat, rng) pv_step, pv10_step, load_step, load10_step = make_step_data(my_predbat, rng) my_predbat.prediction_kernel_enable = True prediction = Prediction(my_predbat, pv_step, pv10_step, load_step, load10_step) prediction.kernel_handle = create_kernel_context(prediction) - charge_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) - export_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) + charge_windows = [make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) for _ in range(window_variants)] + export_windows = [make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, rng.randint(2, 5)) for _ in range(window_variants)] end_record = my_predbat.forecast_minutes jobs = [] for index in range(count): + charge_window = charge_windows[index % window_variants] + export_window = export_windows[index % window_variants] charge_limit = [round(rng.uniform(0, my_predbat.soc_max), 2) for _ in charge_window] export_limits = [rng.choice([100.0, 99.0, 0.0, round(rng.uniform(1, 99), 1)]) for _ in export_window] pv_scenario = rng.choice([PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90]) @@ -891,6 +913,57 @@ def build_batch_jobs(my_predbat, rng, count): return prediction, jobs +def build_batch_reference(prediction, jobs): + """Run one pk_run per job to build the reference results run_prediction_kernel_batch is checked against. + + The SoC series is materialised (unlike the batch path) so the range can be scanned in Python + exactly as thread_run_prediction_charge_min_max does. Returns None if a reference run itself fails. + """ + reference = [] + for job in jobs: + single = run_prediction_kernel(prediction, job.charge_limit, job.charge_window, job.export_window, job.export_limits, job.pv_scenario, job.end_record, 5, False) + if single is None: + print("ERROR: reference pk_run failed") + return None + if job.range_window is None: + soc_range = (prediction.soc_max, 0) + else: + soc_range = prediction.scan_soc_range(single[11], job.range_window) + reference.append((single, soc_range)) + return reference + + +def check_batch_results(jobs, reference, batched, n_threads): + """Compare one pk_run_batch call's results against the build_batch_reference() reference, returns True on failure""" + if len(batched) != len(jobs): + print("ERROR: pk_run_batch returned {} results for {} jobs".format(len(batched), len(jobs))) + return True + + failed = False + for index, (result_tuple, soc_range_min, soc_range_max) in enumerate(batched): + single, (expect_min, expect_max) = reference[index] + if result_tuple is None: + print("ERROR: job {} reported a non-zero status at {} threads".format(index, n_threads)) + failed = True + continue + for field, name in enumerate(RESULT_NAMES): + if result_tuple[field] != single[field]: + print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) + failed = True + # The batch never materialises the SoC series - that is what makes it affordable + if result_tuple[11] != {}: + print("ERROR: job {} returned a SoC series from the batch path".format(index)) + failed = True + for field, name in [(12, "car_charging_soc_next"), (13, "iboost_next"), (14, "iboost_running"), (15, "iboost_running_solar"), (16, "iboost_running_full")]: + if result_tuple[field] != single[field]: + print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) + failed = True + if soc_range_min != expect_min or soc_range_max != expect_max: + print("ERROR: job {} at {} threads SoC range {} {} expected {} {}".format(index, n_threads, soc_range_min, soc_range_max, expect_min, expect_max)) + failed = True + return failed + + def run_batch_parity_tests(my_predbat, count=60): """Check pk_run_batch matches a loop of pk_run exactly, at every thread count, returns True on failure. @@ -905,61 +978,72 @@ def run_batch_parity_tests(my_predbat, count=60): print("SKIP: kernel does not expose pk_run_batch") return False - failed = False prediction, jobs = build_batch_jobs(my_predbat, random.Random(4321), count) if not prediction.kernel_handle: print("ERROR: batch parity kernel context creation failed") return True - # Reference: one pk_run per scenario, with the SoC series materialised so the range can be - # scanned in Python exactly as thread_run_prediction_charge_min_max does - reference = [] - for job in jobs: - single = run_prediction_kernel(prediction, job.charge_limit, job.charge_window, job.export_window, job.export_limits, job.pv_scenario, job.end_record, 5, False) - if single is None: - print("ERROR: reference pk_run failed") - return True - if job.range_window is None: - soc_range = (prediction.soc_max, 0) - else: - soc_range = prediction.scan_soc_range(single[11], job.range_window) - reference.append((single, soc_range)) + reference = build_batch_reference(prediction, jobs) + if reference is None: + return True + failed = False for n_threads in (1, 2, 4, 8): batched = prediction_kernel.run_prediction_kernel_batch(prediction, jobs, n_threads) if batched is None: print("ERROR: pk_run_batch failed at {} threads".format(n_threads)) return True - if len(batched) != len(jobs): - print("ERROR: pk_run_batch returned {} results for {} jobs".format(len(batched), len(jobs))) - return True - for index, (result_tuple, soc_range_min, soc_range_max) in enumerate(batched): - single, (expect_min, expect_max) = reference[index] - if result_tuple is None: - print("ERROR: job {} reported a non-zero status at {} threads".format(index, n_threads)) - failed = True - continue - for field, name in enumerate(RESULT_NAMES): - if result_tuple[field] != single[field]: - print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) - failed = True - # The batch never materialises the SoC series - that is what makes it affordable - if result_tuple[11] != {}: - print("ERROR: job {} returned a SoC series from the batch path".format(index)) - failed = True - for field, name in [(12, "car_charging_soc_next"), (13, "iboost_next"), (14, "iboost_running"), (15, "iboost_running_solar"), (16, "iboost_running_full")]: - if result_tuple[field] != single[field]: - print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) - failed = True - if soc_range_min != expect_min or soc_range_max != expect_max: - print("ERROR: job {} at {} threads SoC range {} {} expected {} {}".format(index, n_threads, soc_range_min, soc_range_max, expect_min, expect_max)) - failed = True + failed |= check_batch_results(jobs, reference, batched, n_threads) if not failed: print("Batch parity: {} scenarios bit-identical to pk_run at 1, 2, 4 and 8 threads".format(count)) return failed +def run_batch_window_variant_tests(my_predbat, count=30, window_variants=6): + """Check the batch's per-job window marshalling picks the right list, not a cached neighbour's. + + build_batch_jobs's default (window_variants=1) shares one charge/export window list across the + whole batch, which exercises run_prediction_kernel_batch's window memo only on its cache-hit path: + every job asks for the same id(windows), so a memo keyed on anything coarser than list identity + would still pass. Task 4's real fan-out mixes windows freely between jobs, so here several distinct + window lists are cycled across the jobs (some jobs sharing a list, most not) and checked against the + same per-scenario pk_run reference run_batch_parity_tests uses - a job that picked up another list's + start/end arrays would simulate the wrong charge/export times and show up as a wrong result. + """ + print("**** Running kernel batch window variant tests ****") + if not prediction_kernel.KERNEL_HAS_BATCH: + print("SKIP: kernel does not expose pk_run_batch") + return False + + prediction, jobs = build_batch_jobs(my_predbat, random.Random(9876), count, window_variants=window_variants) + if not prediction.kernel_handle: + print("ERROR: batch window variant kernel context creation failed") + return True + + distinct_charge = len({id(job.charge_window) for job in jobs}) + distinct_export = len({id(job.export_window) for job in jobs}) + if distinct_charge < 2 or distinct_export < 2: + print("ERROR: batch window variant test only produced {} charge and {} export window list(s) - not exercising the memo".format(distinct_charge, distinct_export)) + return True + + reference = build_batch_reference(prediction, jobs) + if reference is None: + return True + + failed = False + for n_threads in (1, 4): + batched = prediction_kernel.run_prediction_kernel_batch(prediction, jobs, n_threads) + if batched is None: + print("ERROR: pk_run_batch failed at {} threads".format(n_threads)) + return True + failed |= check_batch_results(jobs, reference, batched, n_threads) + + if not failed: + print("Batch window variant parity: {} scenarios across {} charge and {} export window lists bit-identical to pk_run".format(count, distinct_charge, distinct_export)) + return failed + + def kernel_available(): """Ensure the kernel library is built and loaded, returns (available, required_failure)""" if not ensure_kernel_built(): @@ -1040,6 +1124,8 @@ def run_kernel_parity_tests(my_predbat): failed |= run_clipping_parity_tests(my_predbat) if not failed: failed |= run_batch_parity_tests(my_predbat) + if not failed: + failed |= run_batch_window_variant_tests(my_predbat) finally: restore_scenario_state(my_predbat, state) From e29f9d1393f5801605dd59de6e21f18846d1c0ed Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 19:34:49 +0100 Subject: [PATCH 11/24] refactor(prediction): split trial-input building out of thread_run_prediction_* Each thread_run_prediction_* built the trial inputs, ran the prediction and shaped the result. The batch path needs the first and third but not the second, so they are split rather than copied - one definition of what a trial input is, for both paths. No-op: 20 random scenarios byte-identical. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/plan.py | 2 -- apps/predbat/prediction.py | 34 ++++++++++++++++++++++------------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/apps/predbat/plan.py b/apps/predbat/plan.py index 187e4ebab..915f2267e 100644 --- a/apps/predbat/plan.py +++ b/apps/predbat/plan.py @@ -672,8 +672,6 @@ def launch_run_prediction_single(self, charge_limit, charge_window, export_windo """ Launch a thread to run a prediction """ - charge_limit = list(charge_limit) - export_limits = list(export_limits) if self.pool and self.pool._state == "RUN": han = self.pool.apply_async(wrapped_run_prediction_single, (charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step)) else: diff --git a/apps/predbat/prediction.py b/apps/predbat/prediction.py index 91c7bfb83..607d75e43 100644 --- a/apps/predbat/prediction.py +++ b/apps/predbat/prediction.py @@ -224,10 +224,30 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10 # Store this dictionary in global so we can reconstruct it in the thread without passing the data PRED_GLOBAL["dict"] = self.__dict__.copy() + def _prepare_single(self, charge_limit, export_limits): + """Copy the caller's limit lists for a single-scenario trial - shared by thread_run_prediction_single and the batch path. + + The copy used to live in Plan.launch_run_prediction_single, where it protected the caller's + lists from the pool pickling them; the batch path defers the read to flush time, which needs + the same protection, so it belongs with the other trial-input building. + """ + return list(charge_limit), list(export_limits) + + def _prepare_charge(self, try_soc, window_n, charge_limit, all_n): + """Build the trial charge limits - shared by thread_run_prediction_charge/_charge_min_max and the batch path""" + try_charge_limit = charge_limit.copy() + if all_n: + for set_n in all_n: + try_charge_limit[set_n] = try_soc + else: + try_charge_limit[window_n] = try_soc + return try_charge_limit + def thread_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step): """ Run single prediction in a thread """ + charge_limit, export_limits = self._prepare_single(charge_limit, export_limits) ( cost, @@ -255,12 +275,7 @@ def thread_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_w Run prediction in a thread """ - try_charge_limit = charge_limit.copy() - if all_n: - for set_n in all_n: - try_charge_limit[set_n] = try_soc - else: - try_charge_limit[window_n] = try_soc + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) ( cost, @@ -319,12 +334,7 @@ def thread_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, Run prediction in a thread """ - try_charge_limit = charge_limit.copy() - if all_n: - for set_n in all_n: - try_charge_limit[set_n] = try_soc - else: - try_charge_limit[window_n] = try_soc + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) ( cost, From c1f59cb875a23b5084a6043aa3c25ad2d0a14e93 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 19:50:19 +0100 Subject: [PATCH 12/24] perf(plan): batch the prediction fan-out into one kernel call launch_run_prediction_* no longer runs anything: it prepares the trial inputs, queues a job and returns a handle whose first get() flushes the whole batch through a single pk_run_batch call. Window start/end arrays are marshalled once per fan-out rather than once per scenario, cache hits and intra-batch duplicates are resolved in Python first, and anything the kernel refuses falls back to the Python engine per job. Serial for now. 20 random scenarios byte-identical. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/plan.py | 75 ++----- apps/predbat/prediction.py | 57 +++-- apps/predbat/prediction_batch.py | 175 +++++++++++++++ apps/predbat/tests/test_prediction_batch.py | 233 ++++++++++++++++++++ 4 files changed, 458 insertions(+), 82 deletions(-) create mode 100644 apps/predbat/prediction_batch.py diff --git a/apps/predbat/plan.py b/apps/predbat/plan.py index 915f2267e..dd7a806c3 100644 --- a/apps/predbat/plan.py +++ b/apps/predbat/plan.py @@ -20,11 +20,10 @@ import copy import traceback from datetime import datetime, timedelta -from multiprocessing import Pool, cpu_count from const import PREDICT_STEP, PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90, TIME_FORMAT, MINUTE_WATT from utils import calc_percent_limit, dp0, dp1, dp2, dp3, dp4, remove_intersecting_windows, in_car_slot -from prediction import Prediction, wrapped_run_prediction_single, wrapped_run_prediction_charge, wrapped_run_prediction_charge_min_max, wrapped_run_prediction_export +from prediction import Prediction from prediction_kernel import kernel_status_summary from predbat_metrics import metrics import time @@ -669,47 +668,20 @@ def optimise_charge_limit_price_threads( ) def launch_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step=PREDICT_STEP): - """ - Launch a thread to run a prediction - """ - if self.pool and self.pool._state == "RUN": - han = self.pool.apply_async(wrapped_run_prediction_single, (charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step)) - else: - han = DummyThread(self.prediction.thread_run_prediction_single(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step)) - return han + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_single(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step) def launch_run_prediction_charge(self, loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """ - Launch a thread to run a prediction - """ - if self.pool and self.pool._state == "RUN": - han = self.pool.apply_async(wrapped_run_prediction_charge, (loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record)) - else: - han = DummyThread(self.prediction.thread_run_prediction_charge(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record)) - return han + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_charge(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) def launch_run_prediction_charge_min_max(self, loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """ - Launch a thread to run a prediction - """ - if self.pool and self.pool._state == "RUN": - han = self.pool.apply_async(wrapped_run_prediction_charge_min_max, (loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record)) - else: - han = DummyThread(self.prediction.thread_run_prediction_charge_min_max(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record)) - return han + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_charge_min_max(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) def launch_run_prediction_export(self, this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record): - """ - Launch a thread to run a prediction - """ - if self.pool and self.pool._state == "RUN": - han = self.pool.apply_async( - wrapped_run_prediction_export, - (this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record), - ) - else: - han = DummyThread(self.prediction.thread_run_prediction_export(this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record)) - return han + """Queue a prediction and return a handle to its result""" + return self.prediction.queue_run_prediction_export(this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record) def scenario_summary_title(self, record_time): txt = "" @@ -1332,35 +1304,16 @@ def calculate_plan(self, recompute=True, debug_mode=False, publish=True): # Creation prediction object self.prediction = Prediction(self, pv_forecast_minute_step, pv_forecast_minute10_step, load_minutes_step, load_minutes_step10, pv_forecast_minute90_step, load_minutes_step90) + # Serial for now - Task 5 wires this to the threads config + self.prediction.batch_threads = 1 kernel_message, kernel_is_warning = kernel_status_summary(self.prediction) self.log("{}Prediction kernel: {}".format("Warn: " if kernel_is_warning else "", kernel_message)) - # Check if LoadML is active and disable thread pools as it causes lockup due to race conditions with NumPy + # Check if LoadML is active - it used to force the process pool off, which no longer exists; + # the kernel's threads are C++ threads with no fork and no NumPy involvement load_ml_comp = self.components.get_component("load_ml") if self.components else None - load_ml_calculating = False if load_ml_comp: - load_ml_calculating = load_ml_comp.is_calculating() - self.log("LoadML is_calculating {}".format(load_ml_calculating)) - if load_ml_calculating and self.pool: - self.log("Disabling thread pool as LoadML is calculating to avoid lockups") - self.pool.close() - self.pool.join() - self.pool = None - - # Create pool - if not self.pool: - if load_ml_calculating: - self.log("Not using thread pool as LoadML is calculating to avoid lockups") - else: - threads = self.get_arg("threads", "auto") - if threads == "auto": - self.log("Creating pool of {} processes to match your CPU count".format(cpu_count())) - self.pool = Pool(processes=cpu_count()) - elif threads: - self.log("Creating pool of {} processes as per apps.yaml".format(int(threads))) - self.pool = Pool(processes=int(threads)) - else: - self.log("Not using threading as threads is set to 0 in apps.yaml") + self.log("LoadML is_calculating {}".format(load_ml_comp.is_calculating())) # Simulate current settings to get initial data metric, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g = self.run_prediction( diff --git a/apps/predbat/prediction.py b/apps/predbat/prediction.py index 607d75e43..3d48daf4e 100644 --- a/apps/predbat/prediction.py +++ b/apps/predbat/prediction.py @@ -19,9 +19,9 @@ from datetime import timedelta from const import PREDICT_STEP, PV_SCENARIO_PV10, PV_SCENARIO_PV90, RUN_EVERY, TIME_FORMAT -from operator import itemgetter from utils import remove_intersecting_windows, get_charge_rate_curve_cached, get_discharge_rate_curve_cached, find_charge_rate, calc_percent_limit, in_iboost_slot, in_car_slot, charge_curve_to_tuple +from prediction_batch import PredictionBatch, prediction_cache_key from prediction_kernel import create_kernel_context, kernel_supported, run_prediction_kernel @@ -94,12 +94,7 @@ def get_total_inverted(battery_draw, pv_dc, pv_ac, inverter_loss, inverter_hybri return total_inverted -# Pulls (start, end) from a window dict; used to build the prediction cache key without a Python -# level loop over every window -window_bounds = itemgetter("start", "end") - - -class Prediction: +class Prediction(PredictionBatch): """ Class to hold prediction input and output data and the run function """ @@ -224,12 +219,17 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10 # Store this dictionary in global so we can reconstruct it in the thread without passing the data PRED_GLOBAL["dict"] = self.__dict__.copy() + # Deliberately after the PRED_GLOBAL snapshot: a pool worker reconstructs its Prediction + # from that dict and never queues anything, so it has no business carrying a batch. + self.pending_batch = [] + self.batch_threads = 1 + def _prepare_single(self, charge_limit, export_limits): """Copy the caller's limit lists for a single-scenario trial - shared by thread_run_prediction_single and the batch path. - The copy used to live in Plan.launch_run_prediction_single, where it protected the caller's - lists from the pool pickling them; the batch path defers the read to flush time, which needs - the same protection, so it belongs with the other trial-input building. + The copy used to live in Plan.launch_run_prediction_single. It is kept here because the batch + path does not read these lists until the batch is flushed, so a trial has to own the copy it + will eventually be simulated from rather than share the caller's list. """ return list(charge_limit), list(export_limits) @@ -270,6 +270,11 @@ def thread_run_prediction_single(self, charge_limit, charge_window, export_windo ) = self.run_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record=end_record, step=step, cache=self.prediction_cache_enable) return (cost, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g) + def queue_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step): + """Queue a single-scenario prediction, returning a handle - the batch runs on the first get()""" + charge_limit, export_limits = self._prepare_single(charge_limit, export_limits) + return self.enqueue_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, self.prediction_cache_enable) + def thread_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): """ Run prediction in a thread @@ -310,6 +315,11 @@ def thread_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_w final_carbon_g, ) + def queue_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue a charge-window trial prediction, returning a handle""" + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) + return self.enqueue_prediction(try_charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, self.prediction_cache_enable) + def scan_soc_range(self, predict_soc, window): """Return the (min, max) SoC across a charge window - shared by the direct and batch min/max paths. @@ -376,6 +386,16 @@ def thread_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, max_soc, ) + def queue_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue a charge-window trial prediction that also reports the SoC range across that window. + + Uncached, exactly as the direct path is: the SoC range is not part of the cached result, so a + hit would answer with the wrong shape. + """ + try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) + range_window = None if all_n else charge_window[window_n] + return self.enqueue_prediction(try_charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, False, want_range=True, range_window=range_window) + def _prepare_export(self, this_export_limit, start, window_n, export_window, export_limits, all_n): """Build the trial export limits and window list - shared by thread_run_prediction_export and the batch path. @@ -427,6 +447,11 @@ def thread_run_prediction_export(self, this_export_limit, start, window_n, charg ) = self.run_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record=end_record, cache=self.prediction_cache_enable) return metricmid, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g + def queue_run_prediction_export(self, this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): + """Queue an export-window trial prediction, returning a handle""" + export_window, export_limits = self._prepare_export(this_export_limit, start, window_n, export_window, export_limits, all_n) + return self.enqueue_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, self.prediction_cache_enable) + def find_charge_window_optimised(self, charge_windows, charge_limit, is_export=False): """ Takes in an array of charge windows @@ -456,17 +481,7 @@ def run_prediction(self, charge_limit, charge_window, export_window, export_limi # every simulation with a few hundred windows. sim_hash = None if cache and not save: - sim_hash = hash( - ( - tuple(charge_limit), - tuple(map(window_bounds, charge_window)), - tuple(export_limits), - tuple(map(window_bounds, export_window)), - pv_scenario, - end_record, - step, - ) - ) + sim_hash = prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) cached_result = self.prediction_cache.get(sim_hash) if cached_result is not None: # Return cached result diff --git a/apps/predbat/prediction_batch.py b/apps/predbat/prediction_batch.py new file mode 100644 index 000000000..1f3152740 --- /dev/null +++ b/apps/predbat/prediction_batch.py @@ -0,0 +1,175 @@ +# ----------------------------------------------------------------------------- +# Predbat Home Battery System +# Copyright Trefor Southwell 2026 - All Rights Reserved +# This application maybe used for personal use only and not for commercial use +# ----------------------------------------------------------------------------- +# fmt off +# pylint: disable=consider-using-f-string +# pylint: disable=line-too-long + +"""Lazy batching of the prediction fan-out. + +Every optimiser fan-out in plan.py is launch-all-then-collect-all, so the launches can queue instead +of running: each one prepares its trial inputs, appends a BatchJob and returns a BatchHandle, and the +first get() runs the whole batch through a single pk_run_batch call. That pays the Python/C boundary +and the window marshalling once per fan-out instead of once per scenario, and it is the only shape +that lets the kernel spread the work across cores - a Python thread pool cannot (the GIL serialises +it) and a process pool cannot (the parent's pickling is a serial bottleneck); both were measured and +rejected. + +INVARIANT: a caller must not mutate any list or window dict it has handed to a queue_* entry point +until it has read the matching handle. The four fan-outs in plan.py satisfy this; the 20-scenario +byte-identical plan comparison is what keeps it that way. +""" + +from operator import itemgetter + +from const import PREDICT_STEP +from prediction_kernel import BatchJob, kernel_supported, run_prediction_kernel_batch + +# Pulls (start, end) from a window dict; used to build the prediction cache key without a Python +# level loop over every window +window_bounds = itemgetter("start", "end") + + +def prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step): + """Hash a simulation's inputs into its prediction cache key. + + Shared by Prediction.run_prediction and the batch runner so a scenario cannot land under two + different keys depending on which path reached it. Built as one tuple hash to keep the per-window + hashing in C rather than looping in Python, which matters because it runs on every simulation + with a few hundred windows. + """ + return hash( + ( + tuple(charge_limit), + tuple(map(window_bounds, charge_window)), + tuple(export_limits), + tuple(map(window_bounds, export_window)), + pv_scenario, + end_record, + step, + ) + ) + + +def shape_batch_result(job, result, soc_range_min, soc_range_max): + """Shape a full run_prediction result into what this job's thread_run_prediction_* returned""" + shaped = tuple(result[:11]) + if job.want_range: + shaped = shaped + (soc_range_min, soc_range_max) + return shaped + + +class BatchHandle: + """Result handle for a queued prediction - the drop-in for the pool's AsyncResult""" + + __slots__ = ("pred", "job") + + def __init__(self, pred, job): + """Bind the handle to the Prediction that owns the batch and to its own job""" + self.pred = pred + self.job = job + + def get(self): + """Return this job's result, flushing the whole pending batch on the first call""" + if self.job.result is None: + self.pred.flush_batch() + return self.job.result + + +class PredictionBatch: + """Pending-batch state and flushing for Prediction. + + A mixin rather than a separate object so the pending list lives directly on the Prediction that + owns the kernel context, with no reference cycle between the two. + """ + + def enqueue_prediction(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, cache, want_range=False, range_window=None): + """Queue one prediction and return a handle to its eventual result""" + sim_hash = prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) if cache else None + + # The kernel tracks the SoC range itself over a step range, so a min/max job does not have to + # ship an 8928-entry SoC buffer. A negative start step means "no range asked for", which the + # kernel answers with (soc_max, 0) - exactly what the Python all_n path returns unclamped. + soc_range_start_step = -1 + soc_range_end_step = -1 + if range_window is not None: + predict_minute_start = max(int((range_window["start"] - self.minutes_now) / 5) * 5, 0) + predict_minute_end = int((range_window["end"] - self.minutes_now) / 5) * 5 + soc_range_start_step = predict_minute_start // PREDICT_STEP + soc_range_end_step = predict_minute_end // PREDICT_STEP + + job = BatchJob( + charge_limit, + charge_window, + export_window, + export_limits, + pv_scenario, + end_record, + step, + soc_range_start_step=soc_range_start_step, + soc_range_end_step=soc_range_end_step, + sim_hash=sim_hash, + want_range=want_range, + range_window=range_window, + ) + self.pending_batch.append(job) + return BatchHandle(self, job) + + def run_batch_job_python(self, job): + """Run one job through the normal prediction path, for when the kernel cannot take it""" + result = self.run_prediction(job.charge_limit, job.charge_window, job.export_window, job.export_limits, job.pv_scenario, end_record=job.end_record, step=job.step, cache=job.sim_hash is not None) + if not job.want_range: + return tuple(result[:11]) + if job.range_window is None: + return tuple(result[:11]) + (self.soc_max, 0) + return tuple(result[:11]) + self.scan_soc_range(result[11], job.range_window) + + def flush_batch(self): + """Run every pending job: cache hits first, then one kernel call, then any fallbacks""" + pending = self.pending_batch + if not pending: + return + # Cleared before anything runs, so a fallback that re-enters run_prediction cannot see a + # half-flushed batch or flush it a second time + self.pending_batch = [] + + cache = self.prediction_cache + kernel_jobs = [] + duplicates = [] + first_by_hash = {} + for job in pending: + if job.sim_hash is not None: + cached = cache.get(job.sim_hash) + if cached is not None: + job.result = shape_batch_result(job, cached, 0.0, 0.0) + continue + # Two identical trials in one fan-out used to be a cache hit for the second one; the + # batch has to collapse them itself or that hit is lost (~44% of calls are hits) + first = first_by_hash.get(job.sim_hash) + if first is not None: + duplicates.append((job, first)) + continue + first_by_hash[job.sim_hash] = job + kernel_jobs.append(job) + + if kernel_jobs: + # kernel_supported() is a property of the Prediction, not of the individual job - it also + # refuses debug runs, which would otherwise reach the kernel here when the direct path + # would have used the Python engine. save is always None for a queued job: a saving run + # calls run_prediction directly and never fans out. + batched = run_prediction_kernel_batch(self, kernel_jobs, self.batch_threads) if kernel_supported(self, None, PREDICT_STEP) else None + for index, job in enumerate(kernel_jobs): + entry = batched[index] if batched is not None else None + if entry is None or entry[0] is None: + job.result = self.run_batch_job_python(job) + continue + result, soc_range_min, soc_range_max = entry + if job.sim_hash is not None: + # Stored without the SoC/car data to save memory, mirroring run_prediction + cache[job.sim_hash] = result[:11] + ([], []) + result[13:] + job.result = shape_batch_result(job, result, soc_range_min, soc_range_max) + + for job, first in duplicates: + job.result = first.result diff --git a/apps/predbat/tests/test_prediction_batch.py b/apps/predbat/tests/test_prediction_batch.py index 059317aac..1affa757b 100644 --- a/apps/predbat/tests/test_prediction_batch.py +++ b/apps/predbat/tests/test_prediction_batch.py @@ -16,7 +16,13 @@ """ +import random + +import prediction_batch +from const import PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10 from prediction import Prediction +from prediction_kernel import create_kernel_context +from tests.test_kernel_parity import apply_random_scenario, kernel_available, make_step_data, make_windows, restore_scenario_state, snapshot_scenario_state def make_export_windows(minutes_now): @@ -72,9 +78,236 @@ def test_export_trial_does_not_mutate_caller_window(my_predbat): return failed +def make_batch_prediction(my_predbat, seed=7): + """Build a kernel-enabled Prediction plus a charge/export window layout to fan out over""" + rng = random.Random(seed) + apply_random_scenario(my_predbat, rng) + pv_step, pv10_step, load_step, load10_step = make_step_data(my_predbat, rng) + my_predbat.prediction_kernel_enable = True + prediction = Prediction(my_predbat, pv_step, pv10_step, load_step, load10_step) + prediction.kernel_handle = create_kernel_context(prediction) + charge_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, 4) + export_window = make_windows(rng, my_predbat.minutes_now, my_predbat.forecast_minutes, 4) + charge_limit = [round(my_predbat.soc_max / 2, 2)] * len(charge_window) + export_limits = [100.0] * len(export_window) + return prediction, charge_window, export_window, charge_limit, export_limits + + +def test_queued_matches_direct(my_predbat): + """Every queued prediction must return exactly what the direct thread path returns, returns True on failure""" + print("**** Running queued vs direct equivalence tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + try_soc = round(my_predbat.soc_max * 0.8, 2) + + cases = [ + ( + "single", + lambda: prediction.thread_run_prediction_single(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record, 5), + lambda: prediction.queue_run_prediction_single(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record, 5), + ), + ( + "charge", + lambda: prediction.thread_run_prediction_charge(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_PV10, None, end_record), + lambda: prediction.queue_run_prediction_charge(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_PV10, None, end_record), + ), + ( + "charge_min_max", + lambda: prediction.thread_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), + lambda: prediction.queue_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), + ), + ( + "charge_min_max_all_n", + lambda: prediction.thread_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, [0, 2], end_record), + lambda: prediction.queue_run_prediction_charge_min_max(try_soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, [0, 2], end_record), + ), + ( + "export", + lambda: prediction.thread_run_prediction_export(5.0, export_window[1]["start"] + 15, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), + lambda: prediction.queue_run_prediction_export(5.0, export_window[1]["start"] + 15, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), + ), + ] + + for name, direct_call, queue_call in cases: + # The queued run goes first, so the direct run cannot be answered out of the cache the queued + # one just populated - and vice versa, hence the clear between them + prediction.prediction_cache = {} + queued = queue_call().get() + prediction.prediction_cache = {} + direct = direct_call() + if queued != direct: + print("ERROR: {} queued {} != direct {}".format(name, queued, direct)) + failed = True + + if not failed: + print("Queued predictions match the direct path for all five shapes") + return failed + + +def test_batch_is_lazy(my_predbat): + """Nothing runs until the first get(), and one get() flushes the whole batch, returns True on failure""" + print("**** Running batch laziness tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + + handles = [prediction.queue_run_prediction_charge(round(soc, 2), 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for soc in (1.0, 2.0, 3.0)] + if len(prediction.pending_batch) != 3: + print("ERROR: expected 3 pending jobs, got {}".format(len(prediction.pending_batch))) + failed = True + if any(handle.job.result is not None for handle in handles): + print("ERROR: a job ran before its handle was read") + failed = True + + handles[0].get() + if prediction.pending_batch: + print("ERROR: pending batch not drained by the first get(), {} left".format(len(prediction.pending_batch))) + failed = True + if any(handle.job.result is None for handle in handles): + print("ERROR: one get() did not flush the whole batch") + failed = True + + # A second read must not re-run anything + before = handles[2].job.result + if handles[2].get() is not before: + print("ERROR: reading a handle twice recomputed the result") + failed = True + + if not failed: + print("Batch laziness tests passed") + return failed + + +def test_batch_cache_and_dedup(my_predbat): + """Cache hits and intra-batch duplicates must never reach the kernel, returns True on failure""" + print("**** Running batch cache/dedup tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + prediction.prediction_cache_enable = True + + calls = [] + real_batch = prediction_batch.run_prediction_kernel_batch + + def spy(pred, jobs, n_threads): + """Record how many jobs each batch call was handed, then run it for real""" + calls.append(len(jobs)) + return real_batch(pred, jobs, n_threads) + + prediction_batch.run_prediction_kernel_batch = spy + try: + # Three identical jobs in one batch must collapse to one kernel job + prediction.prediction_cache = {} + handles = [prediction.queue_run_prediction_charge(4.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for _ in range(3)] + results = [handle.get() for handle in handles] + if calls != [1]: + print("ERROR: expected one kernel job for three identical trials, got {}".format(calls)) + failed = True + if results[0] != results[1] or results[1] != results[2]: + print("ERROR: deduplicated jobs returned different results") + failed = True + + # And a repeat in a later batch must come from the cache without a kernel call at all + del calls[:] + again = prediction.queue_run_prediction_charge(4.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if calls: + print("ERROR: a cached scenario still reached the kernel: {}".format(calls)) + failed = True + if again != results[0]: + print("ERROR: cached result {} differs from the computed one {}".format(again, results[0])) + failed = True + finally: + prediction_batch.run_prediction_kernel_batch = real_batch + + if not failed: + print("Batch cache/dedup tests passed") + return failed + + +def test_batch_fallbacks(my_predbat): + """A job the kernel cannot take still runs, and gives the Python engine's answer, returns True on failure""" + print("**** Running batch fallback tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + + # Two references, because the fallbacks land on two different engines. A batch the kernel refused + # still re-runs through run_prediction, which dispatches to the kernel; a Prediction the kernel + # will not serve at all re-runs on the Python engine. Those two agree to 1e-6 (kernel_parity), not + # bit-exactly, so each fallback is compared against the engine it actually used. + prediction.prediction_cache = {} + expected = prediction.thread_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) + prediction.debug_enable = True + prediction.prediction_cache = {} + expected_python = prediction.thread_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) + prediction.debug_enable = False + + # 1. Whole batch refused (no kernel, stale binary, or a non-zero return code) + real_batch = prediction_batch.run_prediction_kernel_batch + + def refuse_all(pred, jobs, n_threads): + """Stand in for a kernel that cannot run the batch at all""" + return None + + def refuse_each(pred, jobs, n_threads): + """Stand in for a kernel that ran the batch but rejected every job""" + return [(None, 0.0, 0.0)] * len(jobs) + + for name, stub in (("whole batch", refuse_all), ("per job", refuse_each)): + prediction_batch.run_prediction_kernel_batch = stub + try: + prediction.prediction_cache = {} + got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if got != expected: + print("ERROR: {} fallback returned {} expected {}".format(name, got, expected)) + failed = True + finally: + prediction_batch.run_prediction_kernel_batch = real_batch + + # 2. Debug runs must not reach the kernel from the batch when the direct path would not take it + prediction.debug_enable = True + try: + prediction.prediction_cache = {} + got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if got != expected_python: + print("ERROR: debug_enable fallback returned {} expected {}".format(got, expected_python)) + failed = True + finally: + prediction.debug_enable = False + + # 3. Kernel genuinely unavailable for this Prediction + prediction.kernel_handle = 0 + prediction.prediction_cache = {} + got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if got != expected_python: + print("ERROR: kernel-less fallback returned {} expected {}".format(got, expected_python)) + failed = True + + if not failed: + print("Batch fallback tests passed") + return failed + + def run_prediction_batch_tests(my_predbat): """Run every batched prediction test, returns True on failure""" failed = test_export_trial_does_not_mutate_caller_window(my_predbat) + + available, required_failure = kernel_available() + if not available: + print("WARNING: kernel not available - batch tests that need it are SKIPPED") + return failed or required_failure + + state = snapshot_scenario_state(my_predbat) + try: + failed |= test_queued_matches_direct(my_predbat) + failed |= test_batch_is_lazy(my_predbat) + failed |= test_batch_cache_and_dedup(my_predbat) + failed |= test_batch_fallbacks(my_predbat) + finally: + restore_scenario_state(my_predbat, state) + my_predbat.prediction_kernel_enable = False + if failed: print("**** Prediction batch tests FAILED ****") else: From 267516974d9a1efbfad1f6f50750315f56029a6a Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 20:07:00 +0100 Subject: [PATCH 13/24] test(batch): pin the debug kernel gate by mechanism, not by value The debug_enable case of test_batch_fallbacks asserted a result value, which the two engines agree on to ~1e-6 with every field rounded to 4dp - so it passed whether or not the kernel_supported() gate in flush_batch existed, leaving the one guard that keeps debug runs on the Python engine unpinned. It now spies on run_prediction_kernel_batch and asserts the kernel was never reached, keeping the value assertion alongside. Also: make "a min/max job is never cached" structural rather than a property of the single caller that passes cache=False, since a cache hit on a range job would answer (0.0, 0.0) and silently collapse the optimiser's SoC pruning envelope; cover a range window that starts before minutes_now (the max(...,0) clamp and the wholly-past negative end step were never executed); cover a single prediction at the levels optimiser's coarse step; and fix the garbled module docstring. 20 random scenarios still byte-identical. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction_batch.py | 6 +- apps/predbat/tests/test_prediction_batch.py | 101 ++++++++++++++++++-- 2 files changed, 100 insertions(+), 7 deletions(-) diff --git a/apps/predbat/prediction_batch.py b/apps/predbat/prediction_batch.py index 1f3152740..7694a4e39 100644 --- a/apps/predbat/prediction_batch.py +++ b/apps/predbat/prediction_batch.py @@ -87,7 +87,11 @@ class PredictionBatch: def enqueue_prediction(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, cache, want_range=False, range_window=None): """Queue one prediction and return a handle to its eventual result""" - sim_hash = prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) if cache else None + # A range job is never cached, and that is structural rather than the caller's choice: the + # SoC range is not part of a cached result, so a hit would answer with (0.0, 0.0) and silently + # collapse the caller's SoC pruning envelope. Callers pass cache=False today; ignoring cache + # outright for a range job means a future caller cannot reintroduce that bug. + sim_hash = prediction_cache_key(charge_limit, charge_window, export_limits, export_window, pv_scenario, end_record, step) if cache and not want_range else None # The kernel tracks the SoC range itself over a step range, so a min/max job does not have to # ship an 8928-entry SoC buffer. A negative start step means "no range asked for", which the diff --git a/apps/predbat/tests/test_prediction_batch.py b/apps/predbat/tests/test_prediction_batch.py index 1affa757b..4305f9c00 100644 --- a/apps/predbat/tests/test_prediction_batch.py +++ b/apps/predbat/tests/test_prediction_batch.py @@ -10,16 +10,19 @@ """Tests for the batched prediction fan-out. launch_run_prediction_* no longer runs anything: it queues a job on the Prediction and returns a -handle whose first get() flushes the whole batch through one pk_run_batch call. These tests pin the -two things that makes conditional - that a queued job returns exactly what the direct -thread_run_prediction_* path returns, and that a job the kernel cannot take still runs. +handle whose first get() flushes the whole batch through one pk_run_batch call. These tests pin what +that deferral relies on: that a trial owns its inputs rather than sharing the caller's, that a queued +job returns exactly what the direct thread_run_prediction_* path returns for every job shape and step, +that nothing runs before the first get() and one get() drains the batch, that cache hits and +intra-batch duplicates never reach the kernel while min/max jobs are never cached at all, and that +every job the kernel will not take still runs on the engine the direct path would have used. """ import random import prediction_batch -from const import PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10 +from const import PREDICT_STEP, PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10 from prediction import Prediction from prediction_kernel import create_kernel_context from tests.test_kernel_parity import apply_random_scenario, kernel_available, make_step_data, make_windows, restore_scenario_state, snapshot_scenario_state @@ -127,6 +130,14 @@ def test_queued_matches_direct(my_predbat): lambda: prediction.thread_run_prediction_export(5.0, export_window[1]["start"] + 15, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), lambda: prediction.queue_run_prediction_export(5.0, export_window[1]["start"] + 15, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record), ), + # The levels optimiser runs single predictions at a coarse "fast mode" step (plan_interval_minutes, + # 30 by default), which is the only caller that passes a step other than PREDICT_STEP. It reaches + # both the cache key and the job, so it needs its own case + ( + "single_coarse_step", + lambda: prediction.thread_run_prediction_single(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record, 30), + lambda: prediction.queue_run_prediction_single(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record, 30), + ), ] for name, direct_call, queue_call in cases: @@ -141,7 +152,7 @@ def test_queued_matches_direct(my_predbat): failed = True if not failed: - print("Queued predictions match the direct path for all five shapes") + print("Queued predictions match the direct path for all {} shapes".format(len(cases))) return failed @@ -217,6 +228,27 @@ def spy(pred, jobs, n_threads): if again != results[0]: print("ERROR: cached result {} differs from the computed one {}".format(again, results[0])) failed = True + + # A min/max job must never be cached. The SoC range is not part of a cached result, so a hit + # would answer (0.0, 0.0), collapse the caller's SoC pruning envelope and silently drop + # candidate SoCs from the search. Checked twice: through the public entry point, and by + # asking enqueue_prediction for a cached range job directly - the second is what pins the + # guard as structural rather than a property of the one call site that passes cache=False. + prediction.prediction_cache = {} + for _ in range(2): + prediction.queue_run_prediction_charge_min_max(4.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if prediction.prediction_cache: + print("ERROR: a queued min/max job populated the prediction cache: {}".format(len(prediction.prediction_cache))) + failed = True + + range_handle = prediction.enqueue_prediction(list(charge_limit), charge_window, export_window, list(export_limits), PV_SCENARIO_NOMINAL, end_record, PREDICT_STEP, True, want_range=True, range_window=charge_window[1]) + if range_handle.job.sim_hash is not None: + print("ERROR: a range job was given a cache key despite never being cacheable") + failed = True + range_handle.get() + if prediction.prediction_cache: + print("ERROR: a range job enqueued with cache=True populated the prediction cache: {}".format(len(prediction.prediction_cache))) + failed = True finally: prediction_batch.run_prediction_kernel_batch = real_batch @@ -225,6 +257,46 @@ def spy(pred, jobs, n_threads): return failed +def test_queued_range_window_in_the_past(my_predbat): + """A range window that started before minutes_now must give the direct path's answer, returns True on failure. + + make_windows only ever emits windows starting at or after minutes_now, so the max(..., 0) clamp on + the range start step and the negative end step of a wholly-past window are otherwise never + executed. Both matter: the kernel derives the range from those two step numbers while a fallback + derives it from scan_soc_range, and the two have to agree exactly. + """ + print("**** Running past range window tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + minutes_now = my_predbat.minutes_now + window = charge_window[1] + + cases = [ + # Straddles minutes_now: the start step clamps to 0, the end step is positive + ("straddling", {"start": minutes_now - 120, "end": window["end"], "average": window["average"]}), + # Wholly behind minutes_now: both steps are negative, so no step is ever in range + ("wholly past", {"start": minutes_now - 240, "end": minutes_now - 60, "average": window["average"]}), + # Ends exactly at minutes_now, the boundary between the two cases above + ("ends at now", {"start": minutes_now - 180, "end": minutes_now, "average": window["average"]}), + ] + + for name, past_window in cases: + trial_window = list(charge_window) + trial_window[1] = past_window + prediction.prediction_cache = {} + queued = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, trial_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + prediction.prediction_cache = {} + direct = prediction.thread_run_prediction_charge_min_max(3.0, 1, charge_limit, trial_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) + if queued != direct: + print("ERROR: {} range window queued {} != direct {}".format(name, queued, direct)) + failed = True + + if not failed: + print("Past range window tests passed for all three shapes") + return failed + + def test_batch_fallbacks(my_predbat): """A job the kernel cannot take still runs, and gives the Python engine's answer, returns True on failure""" print("**** Running batch fallback tests ****") @@ -265,15 +337,31 @@ def refuse_each(pred, jobs, n_threads): finally: prediction_batch.run_prediction_kernel_batch = real_batch - # 2. Debug runs must not reach the kernel from the batch when the direct path would not take it + # 2. Debug runs must not reach the kernel from the batch when the direct path would not take it. + # This has to assert the mechanism, not the value: the two engines agree to ~1e-6 and every field + # is rounded to 4dp, so the tuples match whether or not the kernel_supported() gate exists. The + # gate is load-bearing because a debug run needs predict_soc_best and friends populated for the + # debug HTML, and reset_kernel_run_state clears exactly those. + calls = [] + + def spy_batch(pred, jobs, n_threads): + """Record that the kernel batch was reached at all, then run it for real""" + calls.append(len(jobs)) + return real_batch(pred, jobs, n_threads) + prediction.debug_enable = True + prediction_batch.run_prediction_kernel_batch = spy_batch try: prediction.prediction_cache = {} got = prediction.queue_run_prediction_charge_min_max(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record).get() + if calls: + print("ERROR: a debug run reached the kernel batch: {}".format(calls)) + failed = True if got != expected_python: print("ERROR: debug_enable fallback returned {} expected {}".format(got, expected_python)) failed = True finally: + prediction_batch.run_prediction_kernel_batch = real_batch prediction.debug_enable = False # 3. Kernel genuinely unavailable for this Prediction @@ -301,6 +389,7 @@ def run_prediction_batch_tests(my_predbat): state = snapshot_scenario_state(my_predbat) try: failed |= test_queued_matches_direct(my_predbat) + failed |= test_queued_range_window_in_the_past(my_predbat) failed |= test_batch_is_lazy(my_predbat) failed |= test_batch_cache_and_dedup(my_predbat) failed |= test_batch_fallbacks(my_predbat) From a0b8059a66d57c72ab2c2b16df5715d2c4265a59 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 20:25:22 +0100 Subject: [PATCH 14/24] perf(plan): run each batched fan-out across kernel threads args[threads] now sizes the kernel's thread pool rather than a pool of worker processes. The GIL is released for the whole pk_run_batch call, so unlike a Python ThreadPool these are real cores. Also corrects a stale comment in annual.py that still described calculate_plan() as spinning up a multiprocessing Pool; it no longer does, and forcing threads=0 there is now about skipping the C++ kernel's per-call std::thread pool creation on hundreds of tiny per-day plans, not fork safety. Identical results at 1, 2 and 8 threads; 20 random scenarios byte-identical with threading actually on (16 threads, this machine's CPU count). Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/annual.py | 16 +++++----- apps/predbat/plan.py | 12 ++++++-- apps/predbat/tests/test_prediction_batch.py | 34 +++++++++++++++++++++ docs/apps-yaml.md | 4 +++ 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/apps/predbat/annual.py b/apps/predbat/annual.py index 1d9c1413c..3e133c482 100644 --- a/apps/predbat/annual.py +++ b/apps/predbat/annual.py @@ -997,14 +997,14 @@ def prepare_sample(predbat, config, weather, tariff, load_source, day, midnight_ """ reset_sample_state(predbat) - # calculate_plan() spins up a multiprocessing Pool sized from args["threads"] (plan.py) - # unless it is exactly 0. The annual tool plans hundreds of individual days per run, each a - # small, fast calculation, so per-day pool creation is both wasted overhead and, on a - # spawn-based multiprocessing start method, unsafe: pool workers read the module-level - # PRED_GLOBAL dict in prediction.py, which is only populated in the parent process. This - # matches create_headless_predbat()'s own choice for a fully offline run; it is forced here - # too so run_day() behaves the same way against a caller-supplied PredBat instance (such as - # the standard unit test fixture) that has not gone through that bootstrap. + # calculate_plan() sizes the C++ kernel's batch thread count from args["threads"] (plan.py); it + # no longer spins up a Python multiprocessing Pool. pk_run_batch creates and joins its own + # std::thread pool fresh on every call, so leaving threads at its 'auto' default would pay that + # creation cost on each of the hundreds of small, fast per-day calculations the annual tool runs + # - overhead a plan this size cannot recoup. This matches create_headless_predbat()'s own choice + # for a fully offline run; it is forced here too so run_day() behaves the same way against a + # caller-supplied PredBat instance (such as the standard unit test fixture) that has not gone + # through that bootstrap. predbat.args["threads"] = 0 predbat.midnight_utc = midnight_utc diff --git a/apps/predbat/plan.py b/apps/predbat/plan.py index dd7a806c3..c0fff625c 100644 --- a/apps/predbat/plan.py +++ b/apps/predbat/plan.py @@ -20,6 +20,7 @@ import copy import traceback from datetime import datetime, timedelta +from multiprocessing import cpu_count from const import PREDICT_STEP, PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90, TIME_FORMAT, MINUTE_WATT from utils import calc_percent_limit, dp0, dp1, dp2, dp3, dp4, remove_intersecting_windows, in_car_slot @@ -1304,8 +1305,15 @@ def calculate_plan(self, recompute=True, debug_mode=False, publish=True): # Creation prediction object self.prediction = Prediction(self, pv_forecast_minute_step, pv_forecast_minute10_step, load_minutes_step, load_minutes_step10, pv_forecast_minute90_step, load_minutes_step90) - # Serial for now - Task 5 wires this to the threads config - self.prediction.batch_threads = 1 + # The kernel spreads one batched fan-out across threads with the GIL released for the whole + # call, so these are real cores - unlike a Python ThreadPool, which peaked at 1.15x on two + # threads and then degraded below serial (perf/threadpool-prototype). + threads = self.get_arg("threads", "auto") + if threads == "auto": + self.prediction.batch_threads = cpu_count() + else: + self.prediction.batch_threads = max(int(threads), 1) + self.log("Prediction batch using {} kernel thread(s)".format(self.prediction.batch_threads)) kernel_message, kernel_is_warning = kernel_status_summary(self.prediction) self.log("{}Prediction kernel: {}".format("Warn: " if kernel_is_warning else "", kernel_message)) diff --git a/apps/predbat/tests/test_prediction_batch.py b/apps/predbat/tests/test_prediction_batch.py index 4305f9c00..9198e879d 100644 --- a/apps/predbat/tests/test_prediction_batch.py +++ b/apps/predbat/tests/test_prediction_batch.py @@ -377,6 +377,39 @@ def spy_batch(pred, jobs, n_threads): return failed +def test_batch_threads_do_not_change_results(my_predbat): + """A threaded flush must return exactly what a serial one does, returns True on failure. + + pk_run_batch is pinned bit-identical across thread counts at the C level (kernel_parity), so this + is really checking the Python side: that results are matched back to their own job regardless of + how the kernel split the work. + """ + print("**** Running batch threading tests ****") + failed = False + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) + end_record = my_predbat.forecast_minutes + socs = [round(my_predbat.soc_max * fraction, 2) for fraction in (0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)] + + reference = None + for n_threads in (1, 2, 8): + prediction.batch_threads = n_threads + prediction.prediction_cache = {} + handles = [prediction.queue_run_prediction_charge(soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for soc in socs] + results = [handle.get() for handle in handles] + if reference is None: + reference = results + elif results != reference: + for index, (got, want) in enumerate(zip(results, reference)): + if got != want: + print("ERROR: job {} at {} threads returned {} expected {}".format(index, n_threads, got, want)) + failed = True + prediction.batch_threads = 1 + + if not failed: + print("Batch threading tests passed - identical results at 1, 2 and 8 threads") + return failed + + def run_prediction_batch_tests(my_predbat): """Run every batched prediction test, returns True on failure""" failed = test_export_trial_does_not_mutate_caller_window(my_predbat) @@ -393,6 +426,7 @@ def run_prediction_batch_tests(my_predbat): failed |= test_batch_is_lazy(my_predbat) failed |= test_batch_cache_and_dedup(my_predbat) failed |= test_batch_fallbacks(my_predbat) + failed |= test_batch_threads_do_not_change_results(my_predbat) finally: restore_scenario_state(my_predbat, state) my_predbat.prediction_kernel_enable = False diff --git a/docs/apps-yaml.md b/docs/apps-yaml.md index 40dc6e55b..27022a907 100644 --- a/docs/apps-yaml.md +++ b/docs/apps-yaml.md @@ -286,6 +286,10 @@ This will remove the need for a DNS lookup of the IP address every time Predbat If defined sets the number of threads to use during plan calculation, the default is 'auto' which will use the same number of threads as you have CPUs in your system. +Predbat batches each group of simulations into a single call to the C++ prediction kernel, which then +spreads them across this many threads. Results do not depend on the thread count - the same plan is +produced at any setting - so this only trades CPU for planning time. + Valid values are: - 'auto' - Use the same number of threads as your CPU count From 8e2c0e5cfc8f5a3155e7b1119f0abe5b26c691a4 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 20:43:28 +0100 Subject: [PATCH 15/24] refactor(plan): remove the prediction process pool Nothing has launched work into it since the fan-out started batching, so PRED_GLOBAL, the four wrapped_run_prediction_* trampolines, DummyThread and the pool lifecycle all go with it. The pool was measured at 1.11x on 16 cores, with the parent's per-call pickling as the serial bottleneck. Also cleans up the code and comments left pointing at the removed pool: cleanup_pool() and its call sites in predbat.py, the stale "pool" entry in userinterface.py's debug-dump exclude list, and pool-specific reasoning in comments in hass.py and load_ml_component.py. Two tests that used DummyThread purely as a generic result-handle double (not to exercise pool behaviour) now use a small local FakeHandle in test_pv90.py; test_infra.py's simple_scenario() calls Prediction.thread_run_prediction_single directly instead of the deleted wrapper. 20 random scenarios byte-identical. Co-Authored-By: Claude Opus 5 (1M context) --- PHASE_B_BATCH_REFACTOR.md | 227 ------------------- apps/predbat/hass.py | 4 +- apps/predbat/load_ml_component.py | 6 +- apps/predbat/marginal.py | 3 +- apps/predbat/plan.py | 31 --- apps/predbat/predbat.py | 42 ---- apps/predbat/prediction.py | 48 ---- apps/predbat/tests/test_download.py | 2 - apps/predbat/tests/test_export_commitment.py | 1 - apps/predbat/tests/test_infra.py | 4 +- apps/predbat/tests/test_pv90.py | 25 +- apps/predbat/userinterface.py | 1 - 12 files changed, 28 insertions(+), 366 deletions(-) delete mode 100644 PHASE_B_BATCH_REFACTOR.md diff --git a/PHASE_B_BATCH_REFACTOR.md b/PHASE_B_BATCH_REFACTOR.md deleted file mode 100644 index 7d98291cf..000000000 --- a/PHASE_B_BATCH_REFACTOR.md +++ /dev/null @@ -1,227 +0,0 @@ -# Phase B: batch the prediction fan-out from Python - -Working notes for picking this up in a fresh session. Delete this file before the branch merges. - -Branch: `perf/kernel-batch-abi` (4 commits, unpushed, based on `main`). - -## Where things stand - -The C++ side is done, verified and committed. The Python side has not been touched yet — it still -issues one `pk_run` call per scenario. - -| commit | what | -|---|---| -| `a3254924` | `pk_run_batch` ABI added; stop filling the SoC series when the caller discards it | -| `2e71022e` | precomputed SoC percent buckets replace `round_py` in the hot loop | -| `be2510d0` | bucket table verification test; all 6 shipped binaries rebuilt | -| `f813d219` | fix: don't clamp the batch SoC range when none was requested | - -Everything is byte-identical to before: all 20 random scenarios unchanged on metric, cost and all -three PV futures, `kernel_parity` green, full suite green including slow tests (101.22s). - -### What the kernel work bought - -Measured on `cases/random_scenarios.yaml` scenario 0 (the benchmark scenario), `threads=0`: - -```text -calculate_plan 2418.4 ms -> 1758.5 ms -27% - C++ pk_run 1056.5 ms -> 380.5 ms - Python 1361.9 ms -> 1378.0 ms unchanged, as expected -C++ share 43.7% -> 21.6% -``` - -20-scenario benchmark: **42.5s -> 31.6s**. - -## Why Phase B is now the whole game - -**Python is 78.4% of plan time.** The kernel is no longer the bottleneck by a wide margin — per -prediction it is roughly 20us of C++ against ~70us of Python. Every further optimisation has to come -off the Python side, and batching is the mechanism. - -There is a second, independent reason: `pk_run_batch` already takes an `n_threads` argument and -scales properly now (**6.7x at 16 threads, bit-identical at every thread count**), but nothing can -use it until Python submits work in batches. One `pk_run` call per scenario cannot be parallelised — -that was measured and rejected twice, see "Dead ends" below. - -## The design - -### The call sites are already batch-shaped - -This is the key enabler and the reason this refactor is tractable. Every fan-out in `plan.py` was -written for the process pool, so it already reads launch-all-then-collect-all: - -```python -for try_soc in try_socs: - results.append(self.launch_run_prediction_charge(...)) # fan out -for try_soc in try_socs: - resultmid[try_soc] = results.pop(0).get() # then collect -``` - -`DummyThread` exists purely so the non-pooled path mimics that shape. So **the call sites do not need -to change at all** — only what `launch_*` returns and when the work actually happens. - -### Lazy batch - -- `launch_run_prediction_*` stops running anything. It appends a job to a pending list on the - `Prediction` and returns a `BatchHandle(batch, index)`. -- `BatchHandle.get()` flushes the whole pending batch on first call, then returns its own slot. - Subsequent `get()`s read already-computed results. -- Flush: resolve prediction-cache hits in Python first, marshal only the misses into a - `PkBatchJob` array, one `pk_run_batch` call, then shape each job's result. - -Batch sizes this produces (scenario 0, from the profile): - -```text -launch_run_prediction_charge 10,698 -launch_run_prediction_export 5,436 -launch_run_prediction_single 4,752 -launch_run_prediction_charge_min_max 3,294 - ------ - 24,180 launches, ~19,209 reaching the kernel -``` - -`optimise_charge_limit_price_threads` fans out ~1176 at a time (392 candidates x 3 PV scenarios), -`optimise_charge_limit` ~900, `optimise_export` ~628. Those are the batches. - -### Do not duplicate the input preparation - -Each `thread_run_prediction_*` does three things: build the trial inputs, call `run_prediction`, -shape the result. The batch path needs the first and third but not the second. - -**Split them rather than copying them**, so the direct and batch paths cannot drift: - -```python -def _prepare_charge(self, try_soc, window_n, charge_limit, all_n): - """Build the trial charge limits - shared by thread_run_prediction_charge and the batch path.""" - try_charge_limit = charge_limit.copy() - if all_n: - for set_n in all_n: - try_charge_limit[set_n] = try_soc - else: - try_charge_limit[window_n] = try_soc - return try_charge_limit -``` - -Same for export (`export_limits.copy()` plus the private window copy — see traps) and single -(pass-through). Then `thread_run_prediction_*` becomes prepare + `run_prediction` + shape, and the -batch enqueue is prepare + record. - -### min/max jobs - -`thread_run_prediction_charge_min_max` scans `predict_soc` across the charge window to get -`min_soc`/`max_soc`. The kernel now does this itself so the batch does not have to ship an -8928-entry SoC buffer per job (that would be ~84MB on a large batch). Set on the job: - -```python -predict_minute_start = max(int((window["start"] - self.minutes_now) / 5) * 5, 0) -predict_minute_end = int((window["end"] - self.minutes_now) / 5) * 5 -job.soc_range_start_step = predict_minute_start // 5 -job.soc_range_end_step = predict_minute_end // 5 # inclusive -``` - -and read `result.soc_range_min` / `result.soc_range_max` back. - -**When `all_n` is set, Python skips the scan and returns `(soc_max, 0)` unclamped.** Pass -`soc_range_start_step = -1` for those; the kernel returns exactly `(soc_max, 0)` in that case (this -is what `f813d219` fixed). - -### Fallbacks that must keep working - -The batch path only applies when the kernel can run the job. Fall back to running the job through -the existing `thread_run_prediction_*` path, serially, when any of: - -- `KERNEL_HAS_BATCH` is False (binary predates `pk_run_batch` — the loader probes for the symbol) -- `kernel_supported()` is False for the job (no kernel context, `debug_enable`, or a `save` run) -- `pk_run_batch` returns non-zero, or a job's `status` field is non-zero - -A per-job `status` is returned precisely so one malformed scenario cannot discard the fan-out. - -## Traps found the hard way - -1. **`thread_run_prediction_export` used to mutate the caller's window dict** (`export_window[n]["start"] = start`). - That was only safe because each pool worker mutated its own unpickled copy. Any shared-memory - parallelism needs it local. The fix is on branch `perf/threadpool-prototype`: - - ```python - export_window = list(export_window) - export_window[window_n] = dict(window, start=start) - ``` - - Only `["end"]` is ever read back by `optimise_export`, so nothing depends on the write being - visible. **Port this across.** - -2. **`round_py` is poison in any hot loop.** It is `snprintf`+`strtod`, ~96ns, and serialises on - libc's global locale — with constant work per thread it degrades **17x at 8 threads**. Two calls - remain (`iboost_next`, `car_soc_next`), both once per run, both harmless. Do not add more. - -3. **The prediction cache is worth keeping.** ~6,518 of 25,727 calls are hits (44%), saving far more - than the hashing costs. Resolve hits in Python before building the batch. - -4. **Test isolation.** Any new test that calls `calculate_plan` must not use the shared `my_predbat` - fixture — it arrives carrying whatever earlier tests left on it and `calculate_plan` raises. Follow - `run_annual_integration_isolated` / `run_window_cache_tests_isolated`: take a fresh instance from - `create_predbat()` and load a debug YAML. - -5. **`cd` in a Bash tool call does not persist**, and `git checkout` carries uncommitted changes - across branches. Both bit during this session. - -## Verification protocol - -Non-negotiable, in this order: - -```bash -cd coverage && source setup.csh - -# 1. byte-identical plans - the real gate -python3 ../apps/predbat/unit_test.py --random-run \ - --random-template cases/predbat_debug_agile1.yaml \ - --random-scenarios cases/random_scenarios.yaml -python3 ../apps/predbat/unit_test.py --random-compare cases/random_results.json random_results.json -# require: 20 unchanged, +0.0000 on metric, cost and all three PV futures - -# 2. kernel parity (includes the SoC bucket table check) -./run_all --test kernel_parity - -# 3. full suite including slow tests -./run_all - -# 4. quality gates -./run_pre_commit # re-run after the dictionary auto-sorts, then re-stage -``` - -Benchmark by summing `runtime_s` across the 20 scenarios, best of 3. Run-to-run spread is ~2-6%, so -do not trust a single run — that mistake was made earlier in this work and produced a bogus 18% -"win" that turned out to be noise. - -## Suggested order - -1. Port the `thread_run_prediction_export` mutation fix from `perf/threadpool-prototype`. -2. Split `thread_run_prediction_*` into `_prepare_*` + shaping. **Verify parity here** — this step - alone should be a no-op. -3. Add `BatchRunner` / `BatchHandle` and switch `launch_*` to enqueue. Keep `n_threads=1`. - **Verify parity.** This isolates the marshalling win with no concurrency risk. -4. Turn on threading (`n_threads` from the `threads` config). **Verify parity again** — results were - bit-identical at every thread count in the C-level test, so any divergence here is a Python bug. -5. Only then remove the process pool, `wrapped_run_prediction_*`, `PRED_GLOBAL` and `DummyThread`. - -## Dead ends - do not repeat these - -- **Python `ThreadPool` instead of the process pool.** `pk_run` does release the GIL (`ctypes.CDLL`) - and the kernel is reentrant, but per-call Python overhead makes the parallel fraction too small. - Peaks at **1.15x on two threads** then degrades below serial. Recorded with measurements on branch - `perf/threadpool-prototype` (commit message, marked do-not-merge). -- **The process pool itself.** 1.11x on 16 cores; the parent's per-call pickling is a serial - bottleneck. Removing it costs almost nothing. -- **Expecting the batch call itself to be faster.** `pk_run_batch` vs a loop of `pk_run` over 120 - scenarios measured **0.99x**. The C boundary crossing was never the cost. The batch is worth doing - for the Python-side savings and because it is the only way to use threads — not for the call - itself. - -## Related work in flight - -`PR #4536` (`perf/window-bounds-cache`) caches window start/end arrays and the prediction-cache key -tuple, worth **-21%** on its own and independent of this branch. It should compose: it removes Python -per-call work, this removes C++ per-call work. If both land, re-profile before assuming what is left. - -Note that batching **partly subsumes** the window-bounds cache, since a batch ships window bounds once -rather than per call. The `sim_hash` half still matters. diff --git a/apps/predbat/hass.py b/apps/predbat/hass.py index cf4044058..58d48479f 100644 --- a/apps/predbat/hass.py +++ b/apps/predbat/hass.py @@ -164,9 +164,7 @@ def log(self, msg, quiet=True): log_size = self.logfile.tell() if log_size > 10000000 and threading.current_thread() is threading.main_thread(): # Only rotate from the main thread to avoid race conditions with - # component threads that also call log() — a Threading.Lock cannot - # be used here because the logfile object must survive pickle for - # the multiprocessing pool. + # component threads that also call log(). for num_logs in range(max_logs - 1, 0, -1): filename = "predbat." + format(num_logs) + ".log" if os.path.isfile(filename): diff --git a/apps/predbat/load_ml_component.py b/apps/predbat/load_ml_component.py index 8b5425b16..5d58c2546 100644 --- a/apps/predbat/load_ml_component.py +++ b/apps/predbat/load_ml_component.py @@ -736,8 +736,10 @@ async def run(self, seconds, first): self.log("ML Component: No training needed, model age is {} hours".format(dp2(retrain_age_seconds / 3600.0))) if should_train or should_fetch: - # Set load_ml_calculating across all NumPy-heavy work (training + predict + save) - # so that the plan's multiprocessing pool is never fork()ed while Numpy threads are active. + # Set load_ml_calculating across all NumPy-heavy work (training + predict + save). This used + # to gate the plan's multiprocessing pool off while NumPy threads were active (fork() is + # unsafe with live threads); the pool is gone, so this is now purely a status flag surfaced + # via is_calculating() and logged by calculate_plan(). if self.base.prediction_started: self.log("ML Component: Waiting for current prediction cycle to complete before running ML work") while self.base.prediction_started: diff --git a/apps/predbat/marginal.py b/apps/predbat/marginal.py index b4a49c8b8..e1f6635dc 100644 --- a/apps/predbat/marginal.py +++ b/apps/predbat/marginal.py @@ -86,8 +86,7 @@ def calculate_marginal_costs(self): if minute in modified_load: modified_load[minute] += extra_per_step - # Create a fresh Prediction with the modified load; this updates PRED_GLOBAL - # which is safe since we run synchronously (pool is idle at this point) + # Create a fresh Prediction with the modified load. # No need to include 10% extra load as we only run normal simulations. pred = Prediction(self, self.pv_forecast_minute_step, self.pv_forecast_minute_step, modified_load, modified_load) diff --git a/apps/predbat/plan.py b/apps/predbat/plan.py index c0fff625c..c74cc0fb9 100644 --- a/apps/predbat/plan.py +++ b/apps/predbat/plan.py @@ -18,7 +18,6 @@ """ import copy -import traceback from datetime import datetime, timedelta from multiprocessing import cpu_count from const import PREDICT_STEP, PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90, TIME_FORMAT, MINUTE_WATT @@ -64,26 +63,6 @@ def scenario_hash_entry(kind, window_n, value): return acc ^ (acc >> 31) -""" -Used to mimic threads when they are disabled -""" - - -class DummyThread: - def __init__(self, result): - """ - Store the data into the class - """ - self.result = result - time.sleep(0) # Yield control - - def get(self): - """ - Return the result - """ - return self.result - - class Plan: """Plan optimisation mixin for finding optimal charge/discharge windows. @@ -1576,16 +1555,6 @@ def calculate_plan(self, recompute=True, debug_mode=False, publish=True): self.log(line) self.publish_html_plan(pv_forecast_minute_step, pv_forecast_minute10_step, load_minutes_step, load_minutes_step10, self.end_record) - # Destroy pool - if self.pool: - try: - self.pool.close() - self.pool.join() - except Exception as e: - self.log("Warn: failed to close thread pool: {}".format(e)) - self.log("Warn: " + traceback.format_exc()) - self.pool = None - # Record planning duration for SLO metrics self.plan_last_duration_seconds = time.time() - plan_start_time metrics().planning_duration_seconds.observe(self.plan_last_duration_seconds) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index 59f3485f9..c097a7463 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -68,7 +68,6 @@ INVERTER_QUICK_UPDATE_SECONDS, ) from config import APPS_SCHEMA, CONFIG_ITEMS -from prediction import reset_prediction_globals from utils import minutes_since_yesterday, dp1, dp2, dp3 from predheat import PredHeat from octopus import Octopus @@ -271,27 +270,10 @@ def time_abs_str(self, minute): """ return (self.midnight + timedelta(minutes=minute)).strftime("%m-%d %H:%M:%S") - def cleanup_pool(self): - """ - Terminate and clean up the multiprocessing pool if it is active. - - Ensures worker processes are properly terminated to prevent orphaned - processes when the prediction loop exits unexpectedly. - """ - if getattr(self, "pool", None): - try: - self.pool.terminate() - self.pool.join() - except Exception as e: - self.log("Warn: Failed to terminate multiprocessing pool: {}".format(e)) - self.log(traceback.format_exc()) - self.pool = None - def reset(self): """ Init stub """ - reset_prediction_globals() self.text_plan = "Computing please wait..." self.prediction_cache_enable = True self.base_load = 0 @@ -316,8 +298,6 @@ def reset(self): # Forecast.solar API request metrics for monitoring self.currency_symbols = self.args.get("currency_symbols", "£p") - self.cleanup_pool() - self.pool = None self.watch_list = [] self.restart_active = False self.inverter_needs_reset = False @@ -1177,15 +1157,6 @@ def download_predbat_version(self, version): # Kill the current threads self.log("Kill current threads before update") self.stop_thread = True - if self.pool: - self.log("Warn: Killing current threads before update...") - try: - self.pool.close() - self.pool.join() - except Exception as e: - self.log("Warn: Failed to close thread pool: {}".format(e)) - self.log("Warn: " + traceback.format_exc()) - self.pool = None # Perform the update self.log("Perform the update.....") @@ -1609,7 +1580,6 @@ def initialize(self): # "Predbat defaulted it" or "another component already overwrote it" (issue #4494 follow-up). self.args_from_apps_yaml = copy.deepcopy(self.args) self.apps_yaml_override_warned = set() # {arg} already warned about via set_arg_auto() - self.pool = None self.log("Predbat: Startup {}".format(__name__)) self.update_time(print=False) self.started_time = self.now_utc_real @@ -1731,16 +1701,6 @@ async def terminate(self): self.log("Info: Components stopped") await asyncio.sleep(0) - if hasattr(self, "pool"): - if self.pool: - self.log("Info: Terminating thread pool...") - try: - self.pool.close() - self.pool.join() - except Exception as e: - self.log("Warn: Failed to close thread pool {}".format(e)) - self.log("Warn: " + traceback.format_exc()) - self.pool = None self.log("Predbat terminated") def update_time_loop(self, cb_args): @@ -1773,7 +1733,6 @@ def update_time_loop(self, cb_args): # Always clear the active flag, even on early return or exception, so the # web spinner and predbat.active switch don't get stuck on self.expose_config("active", False) - self.cleanup_pool() elif not self.prediction_started: time_now = datetime.now() inverter_data_last_fetch = self.inverter_data_last_fetch @@ -1855,7 +1814,6 @@ def run_time_loop(self, cb_args): # Always clear the active flag, even on early return or exception, so the # web spinner and predbat.active switch don't get stuck on self.expose_config("active", False) - self.cleanup_pool() def run_time_loop_balance(self, cb_args): """ diff --git a/apps/predbat/prediction.py b/apps/predbat/prediction.py index 3d48daf4e..7306b7802 100644 --- a/apps/predbat/prediction.py +++ b/apps/predbat/prediction.py @@ -25,48 +25,6 @@ from prediction_kernel import create_kernel_context, kernel_supported, run_prediction_kernel -# Only assign globals once to avoid re-creating them with processes are forked -if not "PRED_GLOBAL" in globals(): - PRED_GLOBAL = {} - - -def reset_prediction_globals(): - global PRED_GLOBAL - PRED_GLOBAL = {} - - -def wrapped_run_prediction_single(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step): - """Reconstruct a Prediction from the global shared state and run a single-scenario prediction in a worker process.""" - global PRED_GLOBAL - pred = Prediction() - pred.__dict__ = PRED_GLOBAL["dict"].copy() - return pred.thread_run_prediction_single(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step) - - -def wrapped_run_prediction_charge(try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Reconstruct a Prediction from the global shared state and run a charge-window trial prediction in a worker process.""" - global PRED_GLOBAL - pred = Prediction() - pred.__dict__ = PRED_GLOBAL["dict"].copy() - return pred.thread_run_prediction_charge(try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) - - -def wrapped_run_prediction_charge_min_max(try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Reconstruct a Prediction from the global shared state and run a charge min/max trial prediction in a worker process.""" - global PRED_GLOBAL - pred = Prediction() - pred.__dict__ = PRED_GLOBAL["dict"].copy() - return pred.thread_run_prediction_charge_min_max(try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) - - -def wrapped_run_prediction_export(this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Reconstruct a Prediction from the global shared state and run an export-window trial prediction in a worker process.""" - global PRED_GLOBAL - pred = Prediction() - pred.__dict__ = PRED_GLOBAL["dict"].copy() - return pred.thread_run_prediction_export(this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) - - def get_diff(battery_draw, pv_dc, pv_ac, load_yesterday, inverter_loss, inverter_loss_recp): """ Get AC output difference @@ -105,7 +63,6 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10 pv_forecast_minute90_step and load_minutes_step90 fall back to the nominal step arrays when None, so every existing call site that never requests the pv90 scenario keeps working unchanged. """ - global PRED_GLOBAL if base: self.minutes_now = base.minutes_now self.log = base.log @@ -216,11 +173,6 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10 if self.prediction_kernel_enable: self.kernel_handle = create_kernel_context(self) - # Store this dictionary in global so we can reconstruct it in the thread without passing the data - PRED_GLOBAL["dict"] = self.__dict__.copy() - - # Deliberately after the PRED_GLOBAL snapshot: a pool worker reconstructs its Prediction - # from that dict and never queues anything, so it has no business carrying a batch. self.pending_batch = [] self.batch_threads = 1 diff --git a/apps/predbat/tests/test_download.py b/apps/predbat/tests/test_download.py index 5ba19ef1b..b2372e7e2 100644 --- a/apps/predbat/tests/test_download.py +++ b/apps/predbat/tests/test_download.py @@ -1693,7 +1693,6 @@ def _test_predbat_download_main_uses_configured_repository(my_predbat): class DummyPredBat: def __init__(self): self.stop_thread = False - self.pool = None def log(self, *_args, **_kwargs): return None @@ -1725,7 +1724,6 @@ def _test_predbat_download_tag_uses_default_repository(my_predbat): class DummyPredBat: def __init__(self): self.stop_thread = False - self.pool = None def log(self, *_args, **_kwargs): return None diff --git a/apps/predbat/tests/test_export_commitment.py b/apps/predbat/tests/test_export_commitment.py index fdd046ac7..c7ca43d0e 100644 --- a/apps/predbat/tests/test_export_commitment.py +++ b/apps/predbat/tests/test_export_commitment.py @@ -23,7 +23,6 @@ def setup_single_export_window(my_predbat, rate_import=10.0, rate_export=30.0, b my_predbat.load_user_config() my_predbat.fetch_config_options() reset_inverter(my_predbat) - my_predbat.pool = None my_predbat.forecast_minutes = 24 * 60 end_record = my_predbat.forecast_minutes diff --git a/apps/predbat/tests/test_infra.py b/apps/predbat/tests/test_infra.py index 0c8b3220a..0a8160017 100644 --- a/apps/predbat/tests/test_infra.py +++ b/apps/predbat/tests/test_infra.py @@ -9,7 +9,7 @@ # pylint: disable=attribute-defined-outside-init from datetime import datetime, timedelta -from prediction import wrapped_run_prediction_single, Prediction +from prediction import Prediction from matplotlib import pyplot as plt import asyncio import numpy as np @@ -805,7 +805,7 @@ def simple_scenario( metric_keep, final_iboost, final_carbon_g, - ) = wrapped_run_prediction_single(charge_limit_best, charge_window_best, export_window_best, export_limit_best, pv10, end_record=(my_predbat.end_record), step=5) + ) = prediction.thread_run_prediction_single(charge_limit_best, charge_window_best, export_window_best, export_limit_best, pv10, end_record=(my_predbat.end_record), step=5) else: ( metric, diff --git a/apps/predbat/tests/test_pv90.py b/apps/predbat/tests/test_pv90.py index bf61b75e3..3844e2dc9 100644 --- a/apps/predbat/tests/test_pv90.py +++ b/apps/predbat/tests/test_pv90.py @@ -10,7 +10,6 @@ """Tests for the pv90 upside forecast scenario.""" from const import PV_SCENARIO_NOMINAL, PV_SCENARIO_PV10, PV_SCENARIO_PV90 -from plan import DummyThread from tests.test_infra import reset_inverter, reset_rates @@ -785,8 +784,8 @@ def _setup_calculate_plan_with_real_windows(my_predbat): window in each direction to search, so the counting assertions below are actually exercised. threads is forced to 0 - the same idiom already used by test_execute.py, test_random_scenarios.py and - test_single_debug.py - so calculate_plan() takes the synchronous DummyThread fallback instead of - spinning up a real multiprocessing Pool, keeping the test fast and deterministic. + test_single_debug.py - so calculate_plan() sizes the kernel's batch thread pool to a single thread + rather than the 'auto' cpu_count() default, keeping the test fast and deterministic. Returns a snapshot dict for _restore_calculate_plan_with_real_windows. """ @@ -1103,6 +1102,22 @@ def counting(loop_soc, window_n, charge_limit, charge_window, export_window, exp return failed +class FakeHandle: + """Minimal result-handle double with a get(), standing in for a real BatchHandle. + + Used to substitute an encoded result into a launch_run_prediction_* return value without routing + it back through the kernel/batch machinery. + """ + + def __init__(self, result): + """Store the pre-computed result tuple.""" + self.result = result + + def get(self): + """Return the stored result.""" + return self.result + + def test_pv90_charge_limit_results_paired_with_try_soc(my_predbat): """optimise_charge_limit's pv90 results must stay paired with the try_soc that produced them. @@ -1149,7 +1164,7 @@ def encoding_launch(loop_soc, window_n, charge_limit, charge_window, export_wind if pv_scenario in encoded_scenarios: encoded_result = list(handle.get()) encoded_result[0] = loop_soc - handle = DummyThread(tuple(encoded_result)) + handle = FakeHandle(tuple(encoded_result)) return handle original_launch_min_max = my_predbat.launch_run_prediction_charge_min_max @@ -1160,7 +1175,7 @@ def encoding_launch_min_max(loop_soc, window_n, charge_limit, charge_window, exp if pv_scenario in encoded_scenarios: encoded_result = list(handle.get()) encoded_result[0] = loop_soc - handle = DummyThread(tuple(encoded_result)) + handle = FakeHandle(tuple(encoded_result)) return handle original_optimise_charge_limit = my_predbat.optimise_charge_limit diff --git a/apps/predbat/userinterface.py b/apps/predbat/userinterface.py index 236de5dce..1cbacc694 100644 --- a/apps/predbat/userinterface.py +++ b/apps/predbat/userinterface.py @@ -33,7 +33,6 @@ from predbat import THIS_VERSION DEBUG_EXCLUDE_LIST = [ - "pool", "ha_interface", "components", "prediction", From ed15d44fc77bedc1e74252147977434532714192 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 21:24:12 +0100 Subject: [PATCH 16/24] fix(prediction): drain a pending batch before a saving run, and pin result routing Three things the batch was relying on nobody getting wrong. Nothing pinned flush_batch's job->result mapping. Injecting a reversed mapping (batched[len(kernel_jobs) - 1 - index]) passed the prediction_batch, kernel_parity and model_kernel suites in full: every trial in a fan-out would silently take another trial's cost. The hole was that no test compared values across a multi-job batch - test_batch_is_lazy only checked results were not None, and the threading test compared the batch against itself at different thread counts, which cannot see a thread-count-independent Python defect because n_threads goes straight to C. That test is now test_batch_results_match_their_own_job and uses an external oracle: ten distinct try_soc values queued in one batch, each handle compared against thread_run_prediction_charge for the same SoC with the prediction cache cleared between the two runs. The SoCs are asserted to give ten different costs first, so a misrouted result cannot match by coincidence - the previous scenario saturated and gave nine identical costs, hence the trial spread across every charge window and the different scenario seed. With the reversed mapping applied, all ten jobs fail at all three thread counts. A saving run is the only one that populates predict_soc_best and friends. If a batch were left pending across it, the next handle read would flush it and reset_kernel_run_state would blank exactly those attributes - the published plan and the debug HTML would come back empty (verified: 288 entries -> 0 with the guard removed) - and a job flushed after its inputs were mutated would be cached under a key hashed from the old ones. All four fan-outs drain their handles first so neither is reachable, but run_prediction now drains any pending batch when save is set. The guard is a single test of a local on the ~250k non-save calls per plan. pending_batch and batch_threads were initialised only inside __init__'s `if base:` branch, so a Prediction built without a base raised AttributeError on its first enqueue. Nothing constructs one today - the wrapped_* trampolines that did went with the process pool - which is what made it worth closing. Also replaces two kernel_parity assertions that could not fail: the SoC series check now requires the single-scenario reference to have materialised the series the batch omits, and car_charging_soc_next (recorded at minute 0, so identical for every job in a fan-out) is backed by an assertion that the kernel fills it at all. The four thread_run_prediction_* docstrings no longer claim to run in a thread; they are the direct synchronous path the batch falls back to. The four queue_run_prediction_* docstrings now state that inputs are read at flush time and must not be mutated before get(). 20-scenario random-compare: +0.0000 on metric, cost and all three PV futures. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction.py | 65 +++++++-- apps/predbat/tests/test_kernel_parity.py | 25 +++- apps/predbat/tests/test_prediction_batch.py | 141 +++++++++++++++++--- 3 files changed, 196 insertions(+), 35 deletions(-) diff --git a/apps/predbat/prediction.py b/apps/predbat/prediction.py index 7306b7802..5b8ea3acb 100644 --- a/apps/predbat/prediction.py +++ b/apps/predbat/prediction.py @@ -173,8 +173,10 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10 if self.prediction_kernel_enable: self.kernel_handle = create_kernel_context(self) - self.pending_batch = [] - self.batch_threads = 1 + # Outside the `if base:` block on purpose: a Prediction built without a base is still a valid + # object and its first enqueue_prediction would otherwise raise AttributeError + self.pending_batch = [] + self.batch_threads = 1 def _prepare_single(self, charge_limit, export_limits): """Copy the caller's limit lists for a single-scenario trial - shared by thread_run_prediction_single and the batch path. @@ -196,8 +198,11 @@ def _prepare_charge(self, try_soc, window_n, charge_limit, all_n): return try_charge_limit def thread_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step): - """ - Run single prediction in a thread + """Run one single-scenario prediction now and return its result. + + Nothing runs in a Python thread any more: this is the direct synchronous path, kept as the + reference the batch is checked against and as what a queued job falls back to when the kernel + will not take it. """ charge_limit, export_limits = self._prepare_single(charge_limit, export_limits) @@ -223,13 +228,20 @@ def thread_run_prediction_single(self, charge_limit, charge_window, export_windo return (cost, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g) def queue_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step): - """Queue a single-scenario prediction, returning a handle - the batch runs on the first get()""" + """Queue a single-scenario prediction, returning a handle - the batch runs on the first get(). + + The window lists and dicts are read at flush time, not now, so the caller must not mutate + anything it passed in before calling get() on the returned handle. + """ charge_limit, export_limits = self._prepare_single(charge_limit, export_limits) return self.enqueue_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step, self.prediction_cache_enable) def thread_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """ - Run prediction in a thread + """Run one charge-window trial prediction now and return its result. + + Nothing runs in a Python thread any more: this is the direct synchronous path, kept as the + reference the batch is checked against and as what a queued job falls back to when the kernel + will not take it. """ try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) @@ -268,7 +280,11 @@ def thread_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_w ) def queue_run_prediction_charge(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Queue a charge-window trial prediction, returning a handle""" + """Queue a charge-window trial prediction, returning a handle. + + The window lists and dicts are read at flush time, not now, so the caller must not mutate + anything it passed in before calling get() on the returned handle. + """ try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) return self.enqueue_prediction(try_charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, self.prediction_cache_enable) @@ -292,8 +308,11 @@ def scan_soc_range(self, predict_soc, window): return min_soc, max_soc def thread_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """ - Run prediction in a thread + """Run one charge-window trial prediction now and return its result plus the SoC range. + + Nothing runs in a Python thread any more: this is the direct synchronous path, kept as the + reference the batch is checked against and as what a queued job falls back to when the kernel + will not take it. """ try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) @@ -343,6 +362,9 @@ def queue_run_prediction_charge_min_max(self, try_soc, window_n, charge_limit, c Uncached, exactly as the direct path is: the SoC range is not part of the cached result, so a hit would answer with the wrong shape. + + The window lists and dicts are read at flush time, not now, so the caller must not mutate + anything it passed in before calling get() on the returned handle. """ try_charge_limit = self._prepare_charge(try_soc, window_n, charge_limit, all_n) range_window = None if all_n else charge_window[window_n] @@ -373,8 +395,11 @@ def _prepare_export(self, this_export_limit, start, window_n, export_window, exp return export_window, export_limits def thread_run_prediction_export(self, this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """ - Run prediction in a thread + """Run one export-window trial prediction now and return its result. + + Nothing runs in a Python thread any more: this is the direct synchronous path, kept as the + reference the batch is checked against and as what a queued job falls back to when the kernel + will not take it. """ export_window, export_limits = self._prepare_export(this_export_limit, start, window_n, export_window, export_limits, all_n) @@ -400,7 +425,11 @@ def thread_run_prediction_export(self, this_export_limit, start, window_n, charg return metricmid, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g def queue_run_prediction_export(self, this_export_limit, start, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Queue an export-window trial prediction, returning a handle""" + """Queue an export-window trial prediction, returning a handle. + + The window lists and dicts are read at flush time, not now, so the caller must not mutate + anything it passed in before calling get() on the returned handle. + """ export_window, export_limits = self._prepare_export(this_export_limit, start, window_n, export_window, export_limits, all_n) return self.enqueue_prediction(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, PREDICT_STEP, self.prediction_cache_enable) @@ -427,6 +456,16 @@ def run_prediction(self, charge_limit, charge_window, export_window, export_limi KERNEL_PARITY_REVISION (prediction_kernel.py) and PK_PARITY_REVISION (prediction_kernel.cpp) must both be bumped, and the kernel_parity test must pass (cd coverage && ./run_all --test kernel_parity). """ + # A saving run publishes predict_soc_best and friends, and it is the only run that does. If a + # batch were left pending, the next handle read would flush it and reset_kernel_run_state + # would blank exactly those attributes, emptying the published plan and the debug HTML; a job + # flushed after its inputs were mutated would also be cached under a key hashed from the old + # ones, poisoning the shared cache. Draining first makes both impossible. Every fan-out site + # already drains its handles before saving, so this is the class defending its own invariant + # rather than a live fix - and it costs the ~250k non-save calls a single test of a local. + if save and self.pending_batch: + self.flush_batch() + # The cache key is only wanted when the cache is actually in play - a saving run always # simulates - so it is not computed otherwise. Building it as one tuple hash keeps the # per-window hashing in C rather than looping in Python, which matters because this runs on diff --git a/apps/predbat/tests/test_kernel_parity.py b/apps/predbat/tests/test_kernel_parity.py index 919b31fd0..3183e6cdf 100644 --- a/apps/predbat/tests/test_kernel_parity.py +++ b/apps/predbat/tests/test_kernel_parity.py @@ -950,10 +950,17 @@ def check_batch_results(jobs, reference, batched, n_threads): if result_tuple[field] != single[field]: print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) failed = True - # The batch never materialises the SoC series - that is what makes it affordable - if result_tuple[11] != {}: - print("ERROR: job {} returned a SoC series from the batch path".format(index)) + # The batch never materialises the SoC series - that is what makes it affordable. Checked + # against the single path rather than against an empty dict on its own, so this fails both + # if the batch starts filling the series and if the reference stopped filling it (which + # would make the batch's emptiness prove nothing). + if result_tuple[11] or not single[11]: + print("ERROR: job {} SoC series: batch has {} entries, single reference has {}".format(index, len(result_tuple[11]), len(single[11]))) failed = True + # car_charging_soc_next is recorded at minute 0, before any trial limit can move it, so it is + # the same value for every job in the fan-out - comparing it job by job pins that the batch + # assembles it like the single path does, but cannot catch a mis-routed result. That the + # kernel fills it at all is asserted once per run in run_batch_parity_tests. for field, name in [(12, "car_charging_soc_next"), (13, "iboost_next"), (14, "iboost_running"), (15, "iboost_running_solar"), (16, "iboost_running_full")]: if result_tuple[field] != single[field]: print("ERROR: job {} at {} threads differs on {}: batch {} single {}".format(index, n_threads, name, result_tuple[field], single[field])) @@ -988,6 +995,18 @@ def run_batch_parity_tests(my_predbat, count=60): return True failed = False + # The per-job car_charging_soc_next comparison in check_batch_results is only worth anything if + # the kernel actually fills that field - otherwise both sides are the Prediction's own baseline + # copied through, and the comparison is two copies of the same list. Seed 4321 gives this + # scenario cars; assert it rather than assume it, so changing the seed cannot silently hollow the + # comparison out. + if not prediction.num_cars: + print("ERROR: batch parity scenario has no cars - the car_charging_soc_next comparison is vacuous") + failed = True + elif reference[0][0][12][: prediction.num_cars] == prediction.car_charging_soc_next[: prediction.num_cars]: + print("ERROR: car_charging_soc_next was not filled by the kernel, it is the Prediction's baseline {}".format(prediction.car_charging_soc_next)) + failed = True + for n_threads in (1, 2, 4, 8): batched = prediction_kernel.run_prediction_kernel_batch(prediction, jobs, n_threads) if batched is None: diff --git a/apps/predbat/tests/test_prediction_batch.py b/apps/predbat/tests/test_prediction_batch.py index 9198e879d..36bcb3184 100644 --- a/apps/predbat/tests/test_prediction_batch.py +++ b/apps/predbat/tests/test_prediction_batch.py @@ -14,8 +14,9 @@ that deferral relies on: that a trial owns its inputs rather than sharing the caller's, that a queued job returns exactly what the direct thread_run_prediction_* path returns for every job shape and step, that nothing runs before the first get() and one get() drains the batch, that cache hits and -intra-batch duplicates never reach the kernel while min/max jobs are never cached at all, and that -every job the kernel will not take still runs on the engine the direct path would have used. +intra-batch duplicates never reach the kernel while min/max jobs are never cached at all, that every +job the kernel will not take still runs on the engine the direct path would have used, and that every +handle in a multi-job batch comes back with its own job's result rather than a neighbour's. """ @@ -81,6 +82,38 @@ def test_export_trial_does_not_mutate_caller_window(my_predbat): return failed +def test_batch_state_exists_without_a_base(my_predbat): + """A Prediction built without a base must still be able to queue, returns True on failure. + + pending_batch and batch_threads used to be initialised only inside __init__'s `if base:` branch, + so a baseless Prediction raised AttributeError on its first enqueue. Nothing constructs one today + - the wrapped_* trampolines that did went with the process pool - which is exactly why the trap + is easy to walk back into. + """ + print("**** Running baseless Prediction tests ****") + failed = False + prediction = Prediction() + + if prediction.pending_batch != []: + print("ERROR: a baseless Prediction has pending_batch {}".format(prediction.pending_batch)) + failed = True + if prediction.batch_threads != 1: + print("ERROR: a baseless Prediction has batch_threads {}".format(prediction.batch_threads)) + failed = True + + handle = prediction.enqueue_prediction([], [], [], [], PV_SCENARIO_NOMINAL, 0, PREDICT_STEP, False) + if len(prediction.pending_batch) != 1: + print("ERROR: enqueue on a baseless Prediction left {} pending job(s)".format(len(prediction.pending_batch))) + failed = True + if handle.job.result is not None: + print("ERROR: enqueue on a baseless Prediction ran the job") + failed = True + + if not failed: + print("Baseless Prediction tests passed") + return failed + + def make_batch_prediction(my_predbat, seed=7): """Build a kernel-enabled Prediction plus a charge/export window layout to fan out over""" rng = random.Random(seed) @@ -377,42 +410,111 @@ def spy_batch(pred, jobs, n_threads): return failed -def test_batch_threads_do_not_change_results(my_predbat): - """A threaded flush must return exactly what a serial one does, returns True on failure. +def test_save_run_drains_pending_batch(my_predbat): + """A saving run must flush any pending batch before it runs, returns True on failure. - pk_run_batch is pinned bit-identical across thread counts at the C level (kernel_parity), so this - is really checking the Python side: that results are matched back to their own job regardless of - how the kernel split the work. + A save run is the only one that populates predict_soc_best and friends, and it goes down the + Python engine because kernel_supported() refuses save. If a batch were left pending across it, + the next handle read would flush it and reset_kernel_run_state would blank exactly those + attributes - the published plan and the debug HTML would come back empty. All four fan-outs drain + their handles before any save run today, so this pins the guard, not a live bug: it is what stops + a fifth fan-out from introducing one. """ - print("**** Running batch threading tests ****") + print("**** Running save-run batch drain tests ****") failed = False prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat) end_record = my_predbat.forecast_minutes + + handle = prediction.queue_run_prediction_charge(3.0, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) + if handle.job.result is not None: + print("ERROR: the queued job ran before the save run") + failed = True + + prediction.run_prediction(charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, end_record=end_record, save="best") + + if prediction.pending_batch: + print("ERROR: the save run left {} job(s) pending".format(len(prediction.pending_batch))) + failed = True + if handle.job.result is None: + print("ERROR: the save run did not flush the pending job") + failed = True + if not prediction.predict_soc_best: + print("ERROR: the save run published no predict_soc_best, so this test cannot see it being blanked") + failed = True + + # The point of the guard: reading the handle afterwards must not wipe what the save run published + published = dict(prediction.predict_soc_best) + handle.get() + if prediction.predict_soc_best != published: + print("ERROR: reading a handle after a save run changed predict_soc_best ({} entries, was {})".format(len(prediction.predict_soc_best), len(published))) + failed = True + + if not failed: + print("Save-run batch drain tests passed") + return failed + + +def test_batch_results_match_their_own_job(my_predbat): + """Every handle in a multi-job batch must get its own job's result, at any thread count, returns True on failure. + + The oracle is external, and it has to be: flush_batch resolves cache hits and intra-batch + duplicates before the kernel call and then walks the surviving jobs alongside the kernel's + results, so an off-by-one or reversed job->result mapping is easy to introduce and returns a + perfectly plausible cost for every trial. Comparing a batch against another batch cannot see + that - both would be wrong the same way - and neither can sweeping n_threads, which is forwarded + verbatim to C with nothing on the Python side varying with it. + + So each handle is compared against thread_run_prediction_charge for the same try_soc, with the + prediction cache cleared between the two runs so neither can be answered out of what the other + stored. The SoCs are checked to give genuinely distinct costs first, otherwise a misrouted result + could match by coincidence. + + The thread sweep rides along: pk_run_batch is pinned bit-identical across thread counts at the C + level (kernel_parity), so this pins that the Python side routes results the same way however the + kernel split the work. + """ + print("**** Running batch result routing tests ****") + failed = False + # Seed 5 rather than the shared default: this test needs ten trials with ten different costs, and + # the default scenario's battery saturates so that nine of the ten come out identical + prediction, charge_window, export_window, charge_limit, export_limits = make_batch_prediction(my_predbat, seed=5) + end_record = my_predbat.forecast_minutes socs = [round(my_predbat.soc_max * fraction, 2) for fraction in (0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0)] + # Every charge window takes the trial SoC, not just one: moving a single window's limit saturates + # once that window can no longer absorb more, which collapses the costs back together + all_n = list(range(len(charge_window))) + + # The oracle: one direct run per SoC, each from a cold cache so it is genuinely simulated + expected = [] + for soc in socs: + prediction.prediction_cache = {} + expected.append(prediction.thread_run_prediction_charge(soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, all_n, end_record)) + + costs = [result[0] for result in expected] + if len(set(costs)) != len(costs): + print("ERROR: the trial SoCs do not all give distinct costs ({}) - a misrouted result could match by luck".format(costs)) + failed = True - reference = None for n_threads in (1, 2, 8): prediction.batch_threads = n_threads prediction.prediction_cache = {} - handles = [prediction.queue_run_prediction_charge(soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, None, end_record) for soc in socs] + handles = [prediction.queue_run_prediction_charge(soc, 1, charge_limit, charge_window, export_window, export_limits, PV_SCENARIO_NOMINAL, all_n, end_record) for soc in socs] results = [handle.get() for handle in handles] - if reference is None: - reference = results - elif results != reference: - for index, (got, want) in enumerate(zip(results, reference)): - if got != want: - print("ERROR: job {} at {} threads returned {} expected {}".format(index, n_threads, got, want)) - failed = True + for index, (got, want) in enumerate(zip(results, expected)): + if got != want: + print("ERROR: job {} (try_soc {}) at {} threads returned {} expected {}".format(index, socs[index], n_threads, got, want)) + failed = True prediction.batch_threads = 1 if not failed: - print("Batch threading tests passed - identical results at 1, 2 and 8 threads") + print("Batch result routing tests passed - {} jobs matched their own direct run at 1, 2 and 8 threads".format(len(socs))) return failed def run_prediction_batch_tests(my_predbat): """Run every batched prediction test, returns True on failure""" failed = test_export_trial_does_not_mutate_caller_window(my_predbat) + failed |= test_batch_state_exists_without_a_base(my_predbat) available, required_failure = kernel_available() if not available: @@ -426,7 +528,8 @@ def run_prediction_batch_tests(my_predbat): failed |= test_batch_is_lazy(my_predbat) failed |= test_batch_cache_and_dedup(my_predbat) failed |= test_batch_fallbacks(my_predbat) - failed |= test_batch_threads_do_not_change_results(my_predbat) + failed |= test_save_run_drains_pending_batch(my_predbat) + failed |= test_batch_results_match_their_own_job(my_predbat) finally: restore_scenario_state(my_predbat, state) my_predbat.prediction_kernel_enable = False From cee8bdd99e5205293e29de1e190fe607ded8ddbf Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 21:24:27 +0100 Subject: [PATCH 17/24] docs: describe the batch model everywhere the pool used to be The process pool is gone, but several places still document it as how predbat works - and one of them is read by AI coding assistants as ground truth. .github/copilot-instructions.md documented self.pool, wrapped_run_prediction_*, PRED_GLOBAL and DummyThread as current architecture, with code samples an assistant would happily regenerate. Replaced with the batch model: queue through launch_run_prediction_*, first get() flushes the fan-out through one pk_run_batch call, kernel threads rather than worker processes, plus the no-mutation invariant. double_array()'s docstring justified its from_buffer view with "each pool worker is a separate process (multiprocessing with fork), so no buffer is ever shared between workers". That was the stated reason an unsafe-looking construct was safe, so it needed a real replacement rather than deletion: the views are filled on the calling thread before the kernel is entered and only ever read afterwards, so even a buffer deliberately shared between jobs (the window memo) is only read concurrently, and the one thread that could change it is blocked inside the call. Same staleness fixed on the module-level loader state and load_kernel's cache note. plan.py's module and class docstrings still described multi-threaded prediction runs; the planner is strictly serial Python now and the threading lives inside pk_run_batch. The four launch_run_prediction_* docstrings now carry the no-mutation-before-get() invariant, which was documented only in prediction_batch.py's module docstring - a file a contributor adding a fifth fan-out would never open. The window memo comment called window reuse "the bulk of the batching win", true for the charge fan-outs but not the export one, where _prepare_export builds a fresh export_window per job and every one misses the memo. BatchJob's docstring listed step as a field the kernel reads, when run_prediction_kernel_batch overrides it with PREDICT_STEP and only the Python fallback reads it. BatchHandle was described as the drop-in for the pool's AsyncResult. The threads doc said '0' disables threads, when it is clamped up to one kernel thread. Co-Authored-By: Claude Opus 5 (1M context) --- .github/copilot-instructions.md | 51 +++++++++++++------------------ apps/predbat/plan.py | 35 ++++++++++++++++----- apps/predbat/prediction_batch.py | 6 +++- apps/predbat/prediction_kernel.py | 29 ++++++++++++------ docs/apps-yaml.md | 2 +- 5 files changed, 74 insertions(+), 49 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 501f8ac52..9ef7b3fd6 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -88,44 +88,37 @@ The core prediction/planning happens in `Plan` mixin (`apps/predbat/plan.py`) wh - `optimise_detailed_pass()` - Fine-tune charge/export windows - `run_prediction()` - Execute battery simulation via `Prediction` class -### Thread Pool System +### Batched Predictions -**Multiprocessing for predictions** (in `apps/predbat/plan.py`): +There is no process pool and no Python thread pool. Every optimiser fan-out in `plan.py` is +launch-all-then-collect-all, so the launches queue instead of running and the whole fan-out is +handed to the C++ kernel in one call, which spreads it across its own threads with the GIL +released. Python itself is strictly serial. -```python -from multiprocessing import Pool, cpu_count - -# Pool created on demand -if not self.pool: - threads = self.get_arg("threads", "auto") - if threads == "auto": - self.pool = Pool(processes=cpu_count()) - else: - self.pool = Pool(processes=int(threads)) -``` +**How it works** (`apps/predbat/prediction_batch.py`, mixed into `Prediction`): -**How it works**: - -- `self.pool` is a `multiprocessing.Pool` instance (NOT thread pool - uses processes) -- Pool runs prediction scenarios in parallel using `pool.apply_async()` -- Wrapped functions in `prediction.py`: `wrapped_run_prediction_single()`, `wrapped_run_prediction_charge()`, etc. -- Global state shared via `PRED_GLOBAL` dict (copied to child processes) -- Pool configured via `threads` config option: `"auto"` for CPU count or specific number -- Returns `DummyThread` objects when pool disabled (for single-threaded testing) +- `Plan.launch_run_prediction_*()` calls `Prediction.queue_run_prediction_*()`, which builds the + trial inputs, appends a `BatchJob` to `self.pending_batch` and returns a `BatchHandle` +- Nothing has run at that point. The first `BatchHandle.get()` calls `flush_batch()`, which resolves + prediction-cache hits and intra-batch duplicates in Python and sends the remainder through one + `run_prediction_kernel_batch()` / `pk_run_batch` call; every handle in the fan-out is then resolved +- A job the kernel will not take (no kernel, stale binary, debug run) falls back to + `Prediction.run_prediction()`, which is also the direct path `thread_run_prediction_*()` uses +- `threads` config option sets `Prediction.batch_threads`, the kernel's thread count. `"auto"` uses + the CPU count. Results are identical at any thread count - it only trades CPU for planning time **Key pattern**: ```python -# Async call to run prediction in pool -if self.pool and self.pool._state == "RUN": - han = self.pool.apply_async(wrapped_run_prediction_charge, (args...)) - return han -else: - # Fallback to synchronous execution - result = wrapped_run_prediction_charge(args...) - return DummyThread(result) +# Queue the whole fan-out, then read the handles - the first get() runs all of it +handles = [self.launch_run_prediction_charge(soc, window_n, ...) for soc in try_socs] +results = [handle.get() for handle in handles] ``` +**Invariant**: a caller must not mutate any list or window dict it has passed to +`launch_run_prediction_*` until it has read the matching handle, because those inputs are not read +until the batch is flushed. + ### Component System (Critical Pattern) All major features inherit from `ComponentBase` (see `apps/predbat/component_base.py`): diff --git a/apps/predbat/plan.py b/apps/predbat/plan.py index c74cc0fb9..f3efa39f1 100644 --- a/apps/predbat/plan.py +++ b/apps/predbat/plan.py @@ -13,8 +13,9 @@ Implements the search algorithm that finds optimal charge and discharge windows by exploring combinations of price thresholds, window sizes, and SoC targets. -Uses multi-threaded prediction runs to evaluate thousands of scenarios and select -the plan that minimises the overall cost metric. +The search itself is serial Python: each fan-out queues its scenarios through +launch_run_prediction_* and the first handle read flushes them all through one +call to the C++ prediction kernel, which is where the threading now lives. """ import copy @@ -67,8 +68,10 @@ class Plan: """Plan optimisation mixin for finding optimal charge/discharge windows. Implements the search algorithm that explores price thresholds, - window combinations, and SoC targets using multi-threaded prediction - runs to minimise the overall cost metric. + window combinations, and SoC targets to minimise the overall cost + metric. Scenarios are evaluated in batches: launch_run_prediction_* + queues them and reading the first handle runs the whole batch through + one C++ kernel call, which spreads it across its own threads. """ def dynamic_load(self): @@ -648,19 +651,35 @@ def optimise_charge_limit_price_threads( ) def launch_run_prediction_single(self, charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step=PREDICT_STEP): - """Queue a prediction and return a handle to its result""" + """Queue a prediction and return a handle to its result. + + Nothing runs here: the inputs are read when the batch is flushed, so no list or window dict + passed in may be mutated until the returned handle's get() has been called. + """ return self.prediction.queue_run_prediction_single(charge_limit, charge_window, export_window, export_limits, pv_scenario, end_record, step) def launch_run_prediction_charge(self, loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Queue a prediction and return a handle to its result""" + """Queue a prediction and return a handle to its result. + + Nothing runs here: the inputs are read when the batch is flushed, so no list or window dict + passed in may be mutated until the returned handle's get() has been called. + """ return self.prediction.queue_run_prediction_charge(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) def launch_run_prediction_charge_min_max(self, loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record): - """Queue a prediction and return a handle to its result""" + """Queue a prediction and return a handle to its result. + + Nothing runs here: the inputs are read when the batch is flushed, so no list or window dict + passed in may be mutated until the returned handle's get() has been called. + """ return self.prediction.queue_run_prediction_charge_min_max(loop_soc, window_n, charge_limit, charge_window, export_window, export_limits, pv_scenario, all_n, end_record) def launch_run_prediction_export(self, this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record): - """Queue a prediction and return a handle to its result""" + """Queue a prediction and return a handle to its result. + + Nothing runs here: the inputs are read when the batch is flushed, so no list or window dict + passed in may be mutated until the returned handle's get() has been called. + """ return self.prediction.queue_run_prediction_export(this_export_limit, start, window_n, try_charge_limit, charge_window, try_export_window, try_export, pv_scenario, all_n, end_record) def scenario_summary_title(self, record_time): diff --git a/apps/predbat/prediction_batch.py b/apps/predbat/prediction_batch.py index 7694a4e39..7070ba641 100644 --- a/apps/predbat/prediction_batch.py +++ b/apps/predbat/prediction_batch.py @@ -62,7 +62,11 @@ def shape_batch_result(job, result, soc_range_min, soc_range_max): class BatchHandle: - """Result handle for a queued prediction - the drop-in for the pool's AsyncResult""" + """Result handle for a queued prediction: get() runs the batch if it has not run yet. + + Deliberately shaped like a future so a fan-out reads as launch-all-then-get-all, but nothing is + running in the background - the work happens inside the first get(). + """ __slots__ = ("pred", "job") diff --git a/apps/predbat/prediction_kernel.py b/apps/predbat/prediction_kernel.py index 5ecc7755e..1d265d2ed 100644 --- a/apps/predbat/prediction_kernel.py +++ b/apps/predbat/prediction_kernel.py @@ -37,7 +37,7 @@ # Maximum number of cars supported by the kernel (PK_MAX_CARS in prediction_kernel.cpp) KERNEL_MAX_CARS = 4 -# Module-level loader state, inherited by forked worker processes +# Module-level loader state - the library is loaded once per process and shared by every Prediction KERNEL_LIB = None KERNEL_LOAD_TRIED = False KERNEL_STATUS = "not loaded" @@ -215,9 +215,12 @@ class PkBatchResult(ctypes.Structure): class BatchJob: """One queued prediction: its trial inputs, how the result should be shaped, and the result itself. - run_prediction_kernel_batch reads only the input fields and the SoC range steps. sim_hash, + run_prediction_kernel_batch reads only the input fields (charge_limit, charge_window, + export_window, export_limits, pv_scenario, end_record) and the SoC range steps. step, sim_hash, want_range, range_window and result belong to the batch runner in prediction_batch.py, which is the only thing that creates these; they live here so the ctypes layer can be tested on its own. + step is deliberately not one of the kernel's inputs - run_prediction_kernel_batch overrides it + with PREDICT_STEP, so it is only read when a job falls back to the Python engine. """ __slots__ = ("charge_limit", "charge_window", "export_window", "export_limits", "pv_scenario", "end_record", "step", "soc_range_start_step", "soc_range_end_step", "sim_hash", "want_range", "range_window", "result") @@ -280,8 +283,9 @@ def kernel_status_summary(pred): def load_kernel(log=None): """Load and verify the kernel shared library, returns the ctypes library or None. - The result is cached module-wide (including across forked workers); failures - are logged once and result in a permanent fallback to the Python engine. + The result is cached module-wide, so the library is loaded and verified once + per process; failures are logged once and result in a permanent fallback to + the Python engine. """ global KERNEL_LIB, KERNEL_LOAD_TRIED, KERNEL_STATUS, KERNEL_HAS_BATCH @@ -359,8 +363,11 @@ def double_array(values): positional arguments and is several times slower, which matters because these are rebuilt on every simulation. from_buffer returns a view over the array.array, and ctypes keeps the backing object alive through the view's _objects, so the buffer cannot be collected while the kernel is - using it. Each pool worker is a separate process (multiprocessing with fork), so no buffer is - ever shared between workers. + using it. The view is never written to once built: it is filled on the calling thread before + pk_run/pk_run_batch is entered and the kernel only ever reads it, so even a buffer deliberately + shared between jobs (the window memo in run_prediction_kernel_batch) is only read concurrently - + the kernel's worker threads never see a buffer change under them, because the one thread that + could change it is blocked inside the call. An iterable is taken rather than a list so callers can hand over a map/generator and skip materialising an intermediate list - array.array consumes it in C and coerces each item to a double @@ -641,10 +648,12 @@ def run_prediction_kernel_batch(pred, jobs, n_threads=1): # covers this (b_base walks up to job_array._objects), so this list is belt-and-braces: the limit # arrays are held explicitly here rather than relying on ctypes' container keepalive. buffers = [] - # A fan-out reuses the same window lists across most of its jobs, so their start/end arrays are - # marshalled once per distinct list instead of once per job - that is the bulk of the batching - # win. Keyed on identity, with the list retained so an id() cannot be recycled mid-batch. This - # relies on no caller mutating a window list between enqueue and flush (see prediction_batch.py). + # The charge fan-outs reuse the same window lists across every job, so their start/end arrays are + # marshalled once per distinct list instead of once per job - which is most of what those batches + # save. The export fan-out gets nothing from this: _prepare_export builds a fresh export_window + # list per job, so every one of those misses the memo and pays its own marshalling. Keyed on + # identity, with the list retained so an id() cannot be recycled mid-batch. This relies on no + # caller mutating a window list between enqueue and flush (see prediction_batch.py). window_cache = {} def window_arrays(windows): diff --git a/docs/apps-yaml.md b/docs/apps-yaml.md index 27022a907..770842dd3 100644 --- a/docs/apps-yaml.md +++ b/docs/apps-yaml.md @@ -293,7 +293,7 @@ produced at any setting - so this only trades CPU for planning time. Valid values are: - 'auto' - Use the same number of threads as your CPU count -- '0' - Don't use threads - disabled +- '0' - Clamped up to a single kernel thread, i.e. each batch is simulated serially - 'N' - Use N threads, recommended values are between 2 and 8 ```yaml From 8905bb59c1c59400d9b1ccad6a63d9024ec4cf44 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 21:39:04 +0100 Subject: [PATCH 18/24] docs(comments): correct references to batched prediction architecture Fix two comment-only inaccuracies describing the batched prediction system that replaced the multiprocessing pool: 1. copilot-instructions.md: replace outdated bullets describing deleted wrapped_run_prediction_* and PRED_GLOBAL with description of current launch_run_prediction_* batching mechanism. 2. prediction_kernel.py: reword window memoisation comment to accurately describe export window sharing, which depends on the all_n parameter. Co-Authored-By: Claude Opus 5 (1M context) --- .github/copilot-instructions.md | 3 +-- apps/predbat/prediction_kernel.py | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 9ef7b3fd6..fd751f981 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -274,8 +274,7 @@ self.log("Error: Failed with: {}".format(e)) Core prediction happens in `apps/predbat/prediction.py`: - `Prediction` class runs battery simulation in 5-min steps -- Multiprocessing via `wrapped_run_prediction_*` functions -- Global state in `PRED_GLOBAL` dict for process sharing +- Batched predictions via `launch_run_prediction_*()` queuing jobs and `BatchHandle.get()` flushing through the C++ kernel - Optimisation in `apps/predbat/plan.py` via `optimise_all_windows()` ### State Management diff --git a/apps/predbat/prediction_kernel.py b/apps/predbat/prediction_kernel.py index 1d265d2ed..a5b496ca0 100644 --- a/apps/predbat/prediction_kernel.py +++ b/apps/predbat/prediction_kernel.py @@ -650,10 +650,10 @@ def run_prediction_kernel_batch(pred, jobs, n_threads=1): buffers = [] # The charge fan-outs reuse the same window lists across every job, so their start/end arrays are # marshalled once per distinct list instead of once per job - which is most of what those batches - # save. The export fan-out gets nothing from this: _prepare_export builds a fresh export_window - # list per job, so every one of those misses the memo and pays its own marshalling. Keyed on - # identity, with the list retained so an id() cannot be recycled mid-batch. This relies on no - # caller mutating a window list between enqueue and flush (see prediction_batch.py). + # save. Export windows share this memo only when all_n is truthy; otherwise _prepare_export builds + # a fresh one per job. Keyed on identity, with the list retained so an id() cannot be recycled + # mid-batch. This relies on no caller mutating a window list between enqueue and flush (see + # prediction_batch.py). window_cache = {} def window_arrays(windows): From 1b5305ba7b1a27a746d293a52772f27d55b34fad Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 21:39:58 +0100 Subject: [PATCH 19/24] docs: record what the batching refactor measured Keeps the numbers with the plan now the hand-off notes are gone: the serial win is real (31.6s -> 26.3s), threading is flat (~0.8%, inside noise), and the census that explains why - 25,091 batch calls with a median of 6 jobs each, so a fresh std::thread pool is built per call to cover ~180us of work. Co-Authored-By: Claude Opus 5 (1M context) --- .../2026-08-15-phase-b-batch-prediction.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md b/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md index 33406d018..821962474 100644 --- a/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md +++ b/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md @@ -1581,6 +1581,49 @@ Required: 20 scenarios unchanged with `+0.0000` on metric, cost and all three PV Then report, best of 3 each: serial batch vs threaded batch vs the 31.6s pre-Phase-B baseline. +## What it actually measured, once built + +The plan was executed and these are the results, kept here because the hand-off notes this plan was +written from are deleted by the last task. + +**The serial win is the payoff.** 20-scenario benchmark, best of 3: **26.3s** against the 31.6s +recorded before this work (that baseline was inherited, not re-measured on the same machine). It +comes from paying the ctypes boundary and the window marshalling once per fan-out. + +**Threading buys nothing measurable: 26.27s serial vs 26.05s at 16 threads**, inside the 2-6% +run-to-run noise band. Results are bit-identical either way. + +**Why**, from a `n_jobs` census over one benchmark run: + +```text +25,091 pk_run_batch calls carrying 253,899 jobs +mean 10.12 jobs/call, median 6, p95 24, max 363 +97.4% of calls carry fewer than 32 jobs +``` + +This plan's own profile predicted fan-outs of ~1176, ~900 and ~628 jobs. The gap is mostly not a +batching failure: the large fan-out is scoped to one `(loop_price, coarse)` iteration and its ~1176 +launches become ~363 kernel jobs once the ~44% prediction-cache hit rate and the intra-batch dedup +have taken their share. The median of 6 is `optimise_charge_limit`'s min/max pre-pass, which is +genuinely that small. So the batch is collecting whole fan-outs — the fan-outs are just small. + +At ~6 jobs of ~30us each, `pk_run_batch` builds and joins six `std::thread`s to cover ~180us of work. +Thread setup dominates by construction. + +**Where the next change goes**, in order: + +1. **`pk_run_batch` in `prediction_kernel.cpp`** — replace the per-call `std::vector` + with a pool created once at `pk_context_create` and woken per batch. This is the smallest change + with the largest effect, and it makes threading pay at today's batch sizes without touching Python. +2. **`plan.py`, not `prediction_batch.py`**, if larger batches are wanted. The ceiling is + `optimise_charge_limit`'s internal serialisation: the min/max pre-pass computes the SoC-pruning + envelope that decides which `try_socs` are launched at all. Breaking that read-then-decide + dependency means either launching the unpruned SoC set speculatively or running the pre-pass for + every window before any trial — both change optimiser semantics and risk moving plans. + `enqueue_prediction`/`flush_batch` already accept arbitrarily large batches; they need no change. +3. **Not** a batch-size threshold before threading in `run_prediction_kernel_batch` — the C++ already + clamps threads to job count, and a Python-side knob would only hide (1). + ## Notes for whoever picks this up - **`PR #4536` (`perf/window-bounds-cache`) is in flight and independent**, worth -21% on its own. Batching partly subsumes it — a batch ships window bounds once per fan-out rather than per call — but the `sim_hash` half still matters, and `prediction_cache_key()` in `prediction_batch.py` is exactly where that half would land. If both branches merge, re-profile before assuming what is left. From 10c7f73d922a9500b2fe3877b22a4d85420f1549 Mon Sep 17 00:00:00 2001 From: Trefor Southwell Date: Sat, 15 Aug 2026 22:11:05 +0100 Subject: [PATCH 20/24] docs: replace the inherited baseline with a measured one The 31.6s in the hand-off notes did not survive re-measurement. Against the fork point, kernel built from each commit's own source and confirmed active on both sides: 41.74s -> 26.22s serial, 40.02s -> 25.81s at each side's default. Neither side's parallelism is worth much; the win is the batching. Also records that the old process pool died with KeyError outside the __main__ entry point on any spawn-default platform, which removing it fixes. Co-Authored-By: Claude Opus 5 (1M context) --- .../2026-08-15-phase-b-batch-prediction.md | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md b/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md index 821962474..216198f37 100644 --- a/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md +++ b/docs/superpowers/plans/2026-08-15-phase-b-batch-prediction.md @@ -1586,12 +1586,28 @@ Then report, best of 3 each: serial batch vs threaded batch vs the 31.6s pre-Pha The plan was executed and these are the results, kept here because the hand-off notes this plan was written from are deleted by the last task. -**The serial win is the payoff.** 20-scenario benchmark, best of 3: **26.3s** against the 31.6s -recorded before this work (that baseline was inherited, not re-measured on the same machine). It -comes from paying the ctypes boundary and the window marshalling once per fan-out. - -**Threading buys nothing measurable: 26.27s serial vs 26.05s at 16 threads**, inside the 2-6% -run-to-run noise band. Results are bit-identical either way. +**The win is the batching itself, and it is large.** Measured against `a131f12c`, the fork point, +with the kernel built from each commit's own source and confirmed active on both sides, runs +interleaved, best of 3, on a 16-CPU machine. All 20 scenarios byte-identical in every configuration. + +| 20-scenario benchmark | fork point | this branch | delta | +|---|---|---|---| +| parallelism off (`threads: 0`) | 41.74s | 26.22s | **37.2% faster** | +| each side's default (`threads: auto`) | 40.02s | 25.81s | **35.5% faster** | + +The 31.6s figure in the hand-off notes was measured in an earlier session under unknown conditions +and did not survive re-measurement — do not carry it forward. + +**Neither side's parallelism is worth much.** The fork point's 16-process pool bought 41.74s → 40.02s +(4%); this branch's 16 kernel threads buy 26.22s → 25.81s (1.6%), inside the 2-6% noise band. The +entire improvement is the batching and the marshalling it removes, not concurrency. + +**The fork point's process pool was also broken outside the `__main__` entry point.** Its workers +rebuild their `Prediction` from a module global populated only in the parent, which requires `fork` +start semantics; `hass.py` sets those only under `if __name__ == "__main__"`. On macOS (spawn by +default since 3.8) every worker therefore started empty and every scenario died with +`KeyError: 'dict'` — the benchmark above needed `fork` forced to get comparable numbers out of the +baseline at all. This branch removes that failure mode by removing the pool. **Why**, from a `n_jobs` census over one benchmark run: From b633d4f1e5cb6b2b4ddab54fdb97ab1eb6b2d700 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 15 Aug 2026 21:23:31 +0000 Subject: [PATCH 21/24] chore: update prediction kernel binaries for all platforms --- apps/predbat/prediction_kernel_lib_aarch64.so | Bin 247216 -> 247200 bytes apps/predbat/prediction_kernel_lib_armv7l.so | Bin 197728 -> 197712 bytes .../prediction_kernel_lib_darwin_arm64.so | Bin 304200 -> 304200 bytes .../prediction_kernel_lib_darwin_x86_64.so | Bin 268934 -> 268934 bytes apps/predbat/prediction_kernel_lib_i686.so | Bin 228908 -> 228888 bytes apps/predbat/prediction_kernel_lib_x86_64.so | Bin 257112 -> 257096 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/predbat/prediction_kernel_lib_aarch64.so b/apps/predbat/prediction_kernel_lib_aarch64.so index 90e1fd8ed70e4aa093223ffebb0e00edd529de70..a9e14491c592cb2a9b68cf2a202fc4143d76cb1f 100755 GIT binary patch delta 89 zcmdnc&A*_Ve}V?%gGS9(O~zJDrmdRH?R(Xea}x8?70ObJiZk=`6pRe@4D}2cd@}R0 pQ;Vz=e0*G>Lfc>NWp-!WuD73AiH%WXdf-uJbH*FfJC8D}0{}g69Vh?* delta 107 zcmZ3`&A*|We}V?%hepj-O~zJDrmdRH?Rzaf@^e#@ic-rJl5-OC(iO^5i;6Sz^AwB> z^$hha7<@AGvQvw!6yU0Sd|aS%+pq6sc4yqKu%B6hjnQhl<56aF##hrTk20$R0LIQE A?f?J) diff --git a/apps/predbat/prediction_kernel_lib_armv7l.so b/apps/predbat/prediction_kernel_lib_armv7l.so index 47f6f9624bc65544e941ceffe4f09651c261e2ad..11f649bb6018643bd06bd844ef586b6130253192 100755 GIT binary patch delta 112 zcmaFR!E>R5XMzIrhyP5C%B{+bTa}r7|EVYEB<7_nl%*CGXXfWA7#Zpr>KQQjWaee3 y7Fj9y__#oYwy*rhRL{6ojrkfgqsH{V%*@J+Go~xDFsn=4_{YQ`%E$l*FeU&)+#X*5 delta 130 zcmcc6!SkSlXMzGV0|RrTa;q}qR%IsNf0iEkxv5D-spSgEIf;4c3T3H9#hLke3Py%{ zhI$qZKACyhsYO-_a8*7&E>OAc)BiEmGj5e&zQW9CHT^9!vohnV>4GfG>JqR1F)@fT JGQa_h2>^`IBRK#7 diff --git a/apps/predbat/prediction_kernel_lib_darwin_arm64.so b/apps/predbat/prediction_kernel_lib_darwin_arm64.so index e422a1c7c753323c33afbb80a7ff2660854629ee..d078737e80600c5668e27f7987b8a3c26852708f 100755 GIT binary patch delta 23508 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 J z)HH6#Wy?2=nR)H<+8YYWm)JeVo$T!0{B!H4U*5m#&!gM(KK`iY`VEl@_iown`Q5Af zm$g0dMS1&>fcb~sUzA__?#FK>y!%IMPs+#TmBY5pUhvA}p|dW?*t&dP%;%qsJo0&N z(py{oL!7x=l1C(*+Vr2dzrTN@-K+85;ayR_8FO+6=idC~O}pOs=)5g2ZvC?9{>fqX z2S+VS{Lefq?Fz?^g=a_JzjDz}Nwrsg8dN&*`Jf9I{AK&M8{Rl_;krKtM4c{)y~_8A zm%o@FbKk@7EPHyf-{b|W|M~u>mnFUP>X=nuccqRR;e2!RgHIMYd;YfKsngD5vp;>g zdFK=P7jDXHzpMGL*L@Z~*6aAIC!SAy;p!hV{$AbGT6fHu|G-_ZESpjNr|Z|B4*pB_ zJI|yaaGYtY{G|Q9Pnz!Cc;keMSu?)bU3}uuQ{VjUXzBGYy*uV&@8f^J;)VR%&Nlz} uV9%*Rhrih}zj15I-yNYh>|gQntH(pXtbV@vp$YdcneBH%f4R$X@BadoY)T#g diff --git a/apps/predbat/prediction_kernel_lib_darwin_x86_64.so b/apps/predbat/prediction_kernel_lib_darwin_x86_64.so index 7ffdaf0309992a88b4fd6757d7c4568042e70630..f09aae1a5d4fd733da68c001968220ce3c4eba2c 100755 GIT binary patch delta 113 zcmZqMD$ur7V1fvv#YWL^cHII71_lWrW&&ac21YQ}&&bbB)h{Z|%S$cNFV8Q^)=x?- zDJV)!nLLl(e)0o$3ju+mjRqzcZMzoBiJXnxXSHLp28RXEgytxY_9zZUAZ7w$=Iv1& HEIL8}o~9oL delta 115 zcmZqMD$ur7V1fvv!$#3?cB2Xg1_lWrW&&ac21YQ}4=qkDD%LM4N=?fzD$Xx0$tX|F z$hESWr$-G1^_c54Br9ziYj8sp~Hx_7C!S8bA?tiWN>oWRkZz`+Q_OhC-M KJ%NKoO$Y!b8X=|t diff --git a/apps/predbat/prediction_kernel_lib_i686.so b/apps/predbat/prediction_kernel_lib_i686.so index b91da501480cf51e8842165e239d022ae04e7cfd..b4024ef8a9524270dbaee49557cb0db63c71a849 100755 GIT binary patch delta 93 zcmZ4Uhj+#w-U$kf4;mF)6&YID&uf2?IzmUvLX%im z)HBqxVDQPz%T6t_Qh=-S@o|C5ZNFc^tjV~Yt%~^?Go#h?yS2>9jGv}6)-j6%0Q#mQ A*#H0l diff --git a/apps/predbat/prediction_kernel_lib_x86_64.so b/apps/predbat/prediction_kernel_lib_x86_64.so index 609e1471e3da306f77b0cbe0504d525dc6c5bb1e..2dfecb538916cb4e0920d67e7d70055d53939558 100755 GIT binary patch delta 85 zcmV-b0IL7k*bm6q50EGUh=D1EDFKBk0<|dvFXWeDp!vd$j?npDoQO^NX|*jOIIjMEh^5;&r>im z)HBqxVDQPz%T6t_Qh=-S@o|C5ZLfdA?9Mn{-~lts_A^hJW!M<4rZYZZ7N7QpS%GoV Jbj3H!>HtpMCs6 Date: Sun, 16 Aug 2026 10:01:09 +0100 Subject: [PATCH 22/24] fix(kernel): bump the ABI to 4 so a pre-batch binary is rejected, not loaded a3254924 made PkScenario::soc_out optional - Python passes no SoC buffer for a cached run, which is the common case - but left PK_ABI_VERSION at 3. An ABI 3 binary writes to soc_out unconditionally, so loading one against this Python is a null write on the first prediction: predbat segfaults instead of falling back to the Python engine. Reproduced by building the kernel from main and pointing PREDBAT_KERNEL_SO at it: model_kernel exits 139. With the bump the loader reports 'stale binary (abi 3 revision 5, expected abi 4 revision 5)' and uses the Python engine, which is what the version check exists to do. Anyone with a locally built .so from an older checkout, or an install whose per-architecture binary was not replaced, would have hit this. All six shipped binaries rebuilt at ABI 4. Co-Authored-By: Claude Opus 5 (1M context) --- apps/predbat/prediction_kernel.cpp | 7 ++++++- apps/predbat/prediction_kernel.py | 2 +- apps/predbat/prediction_kernel_lib_aarch64.so | Bin 247200 -> 247216 bytes apps/predbat/prediction_kernel_lib_armv7l.so | Bin 197712 -> 197728 bytes .../prediction_kernel_lib_darwin_arm64.so | Bin 304200 -> 304200 bytes .../prediction_kernel_lib_darwin_x86_64.so | Bin 268934 -> 268934 bytes apps/predbat/prediction_kernel_lib_i686.so | Bin 228888 -> 228908 bytes apps/predbat/prediction_kernel_lib_x86_64.so | Bin 257096 -> 257112 bytes 8 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/predbat/prediction_kernel.cpp b/apps/predbat/prediction_kernel.cpp index 79bc6c776..6b1d2bde6 100644 --- a/apps/predbat/prediction_kernel.cpp +++ b/apps/predbat/prediction_kernel.cpp @@ -28,7 +28,12 @@ #include #include -#define PK_ABI_VERSION 3 +// ABI 4: PkScenario::soc_out may be null, and pk_run_batch was added. The null is the reason this had +// to move - Python now passes no SoC buffer for every cached run, and an ABI 3 binary writes to it +// unconditionally, so loading one against this Python segfaults on the first prediction rather than +// falling back. Bumping makes the loader reject it and use the Python engine, which is the whole +// point of the check. +#define PK_ABI_VERSION 4 #define PK_PARITY_REVISION 5 #define PK_MAX_CARS 4 #define PK_RUN_EVERY 5 // const.py RUN_EVERY diff --git a/apps/predbat/prediction_kernel.py b/apps/predbat/prediction_kernel.py index a5b496ca0..27f5f21b9 100644 --- a/apps/predbat/prediction_kernel.py +++ b/apps/predbat/prediction_kernel.py @@ -31,7 +31,7 @@ from utils import get_curve_value, find_battery_temperature_cap, in_car_slot, in_iboost_slot # Expected ABI/parity revisions of the shared library (see prediction_kernel.cpp) -KERNEL_ABI_VERSION = 3 +KERNEL_ABI_VERSION = 4 KERNEL_PARITY_REVISION = 5 # Maximum number of cars supported by the kernel (PK_MAX_CARS in prediction_kernel.cpp) diff --git a/apps/predbat/prediction_kernel_lib_aarch64.so b/apps/predbat/prediction_kernel_lib_aarch64.so index a9e14491c592cb2a9b68cf2a202fc4143d76cb1f..4d99d07550a421674b22aecedbc12a4eea173605 100755 GIT binary patch delta 117 zcmZ3`&A*|We}V?%hepka@()(Wp-!WuCSk3fsN5>y5mu1bH-QG JD~~d(0{|U(DUJXD delta 99 zcmdnc&A*_Ve}V?%gGSA*nv9177!%sx1~39K)AqLk%!hN-lXDXD(iO^5i;6Sz^AwB> y^$hh47<@AGvQvw!6nuPKphDYU?qzmo+^)BuS&5BNV|w6GW^=|H(>sqcs{;Te3nHih diff --git a/apps/predbat/prediction_kernel_lib_armv7l.so b/apps/predbat/prediction_kernel_lib_armv7l.so index 11f649bb6018643bd06bd844ef586b6130253192..b2d0a0bd4cc8abd5a4a08d59284059f02fa523f2 100755 GIT binary patch delta 139 zcmcc6!SkSlXMzGV0|WC$<%J!LEX_wd+K+ZHZa><=w7S&NBR@AasVKEvAvq^8FI}N5 zwWv5VKTpBPP|r}$g25*G delta 121 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 M#N!U76^aJ`57m(CJOBUy delta 63962 zcmZ^s4}4U`x&CK%6WBnI4N2I9Kbs98EdL}(BtbxSAxe;l0b`9V>PDk30umIj0l{4) ztx>Qhp0p<_%A!~U#x_)J6N|c7dK)YEHYly>E$!VPt&3p06sj9dl-&M(|BvIm zah@+t;+u?lLuO@%cFIPVsv6!J%Gd-pg6%T44{>B4Iv}I+pp5+!2NzMhaS+jQkIQI8 z_LD8M$!Lesg=j{TjC%SS%vka;8ErSxhB|nuF?Hyy?7SD{J~36pNE}Gizt7k>)REo% z0~xJSHMrr3h@Lj~qK1=3+t8)lWpJA#`{)yL&(mtpsuZ#3WvtVfjp$+33pB6q=OA_# z^)wk3h%VSI%Vwyk1#K9G=mMi2(X2;h)T5k!UDfP2jv(4f{K>&yqUK%3c|_MWsIsbe zclMPP$IVTdh4!yZaV%>lHT+7|&{I3GRYNd7qUKng{5vE z8l!%kV_v5!)k32AYV39MXt%>g+IUBxos`m@>?Ay{wj+eAPO>QB3)InLgzG-4`o7C( zvzY3v<}awxuo14irOna%>ru@zxYH4Eky5&Qd4&7bb|K+4KbJ%0A-v=b$%_duQ@m92 zVc&Ldow3pB$gWXgA1PLA>~;1hc9n77>9{pW_UTmHwUozXQ|bthDBehT)R>*)$d0LK z6Nz3lDsmi#F9$OOi7=O(3&O_s9OMm&+Rw{YbP#?{aou`4OcAnw#ryK)ixM7F+e!o9 z8mni6I4MxCDzZH(Pab_>pW3z)-l+`9B3#?(8o)6tM~#E7ejoD&gc-YNbh$7Ax@-Xt ziD(~-36CkKN(qlEUQW1nR(D8uP@e#PxqrV?ZOV}yj1PqPI$TE9fWJQbf<`00Tv+zF6cxgT)Pz~ zymY6`Gp1A@KaP5}8j}K?xCUn$TIkDd@7b$kp*gnx=1Si@8c_gBpDkMCr9Ptny zQ@ogP?Ue42?ugE-a=CwhUgi8wT`x&R+NmnS+tqe8;msqEEBFZ#?!HX&+5vn%WBXK~ zZa{!B*GO5Qk?@NuaYM$&iH<-MiE95^2w$gaYbAV>;$gy%Dz3Xp{p*nX_xra(`PWG* z(*8vWH{X_i#|a;=xNX%KftjaKkxym|>snHcBVkvWo|V7@K)W7AZHplO5T9 z5)Hp0qt(XV$&R#I5}jxqoQ#=ovW+*1IBzxh6i0SD*=wz8EbhpsIF?08G^&meCw#H$ zitVX^T^!n`x@gqnSZ)&C{f>+l8b=TMExYXOhv1WT(={;mP8L8mNhpT zD-mrX(K}SxR%5%{k=9P4$BcTn!w9==X;BjS595g2k+Msbwiz3zI(U|mHr0{l{^7uW zXBoLu9Y*O?j39};{%x;NI?Yd_zc#j`Tnoz8lE^4kuF*J-a!n+<(C9)r`!rj2JBiFx zBZKjr=17Z@Xo2CK=E&9i*q$EPi=pb6Sw{Udj2?-;q@ox-M2kuE1C=QlJw*K^8dKwg z(VLFZBhjz>M{hb@obER2rrV6*bazEwoor!*l+crTlyE(n#|V$A87EG7%s7uDdS==J zHgzODOZ2D`cEa`Sltp;BM9y_C!rK*h6Ru}>)x%NWUUu~KUT7Sj;Rtw0F+CTR65gb? z%L&&;`3ToW`3cuXRY~4|-yAc%Go@2OQbapdOSpEbj_}SaoG5U!o-BwRZcAzV8Zl|0d@`YWVUaZ*G(#Z(h?u4$)igqN(6 zPT2`BQ#^}s?Ud@`V5i*1##xR)9x0}s@(|vrwu=eZPL&d_ohm0>JLQu+(W$OkxI)dc z1*%99?Nl}4+NmJnJ<5?24%QK_ol;#K>{Q4&l80LpQcOG5O1S+QnNwlHwNvec zYo|I0*G_dxp6Jx<+0v;fDWaW<5w4wz6K*S$jxg0^or8A8ZG>y5R2K(3g$v@9c)lma zv{QM6*Q)J8!nIQ#!nISyglnftB~Nr}`<1vaztR@)ks{hDKjGS`D#DK`N2&=wp?HvR z?Ud@`V5jPgiaCxzBPphxY9gE&GN)Py*G{z(uAK@KuAOR^JkhD+bEH$9q=rC7kK~C? zYCA-@ zcB+YR?Nkfl+NoB_6P?;PS31>BifE@g2-i+^5?*qfbSgr4nc`8xwNo+4`=9Fc{ZyP3 zNIoVX8CZin&uEs}3HPh*EW)*St^s@wW7<6TfB@cCsXNO&!ehpf0z8Kl;7t{YXzz*% z*WQ&9UU-M}uAFd>;y%K)cdCnnv#iS4Tj&T>lVUo{Y6*|1?K;A>Q;mdcqe6shqnad7 z%(Aq3(y3NbL^~BGTszfH_-dbYs)O)K#XAYtPN^;qb}DL|pXUg~NHOgc`_aH$D_7e# z!nIR&!nIRbglnfK8Zy5mHP$6(hX($1=y_glngmitG7KJ7ptWJ7t$V(J8*r@ytS7 zz(q=EquhjRqw)y9_<%I3knkSGJ%nqcR1XImRcdrCbOg#tF>REe@UYshB3v6)O}I8H zNVqntR`NunR$kL*R3j;&jS3O2jcOu%--FVq7Q&kqZzWtCrFuBnsCHxaB1fQu6w^jU z2ro2cMnwtNM#Tu%M#Tx&Mlo4mqEUMnIgHRETfnXkrIS-Tl|{IA%0+nTL((ZX;pK|w z5w4w5T^#I`$Jp+11d2&9?NmA8Eo$3GxOU1MesYB76vJtMGvJ+mpSvr+P_&UX1glnf%7Y93)XXGw%1PVzp?Nl-0A+=pfxOS?X zaP5?jaP5>|@KNVs;Ymhi3HrBii;*C^gdxOPf)aj;WO#>OH? zpoJ9EPK622dRFFCJK@@?4#KrlorG(rB9bRM)m0>&ijgAPsW{=fFvjzO5 zh<2)qaP3qz;o%=hr-FpHD_%=@sanjZx;WUWMk8&hBM>6Rv{NmF+n$p-)k?T_DonU` zs-1A{REOk=PHkT*or;hm+Nmhv+Nl`fEvn~n!dn$*sw+AN{k19wB_HgR-KZ#b1hPmm z?UbAFpxVwOTsu`rxOU1zxOS>o@!nj2q=1mM#8m8A;PsuO@wQcS|m?2=}3t*DNKrJliCT_CUp>=^prHIlkilj>9b z)=0R{vXJD7SypkQbgG3E(N47zuAK@K-uaAls-5tN;vIx*r&JdQI~6g!rH(+96w^+{ z2`_y?<``3|Cpn!{Ho~=2cEYt&S&}C@b+8nRMoMh~Hz}f>$|GDmRY-X2kEBx`!o!Le z6Rw?7T^#IGxlzB;5%7^>+NmnS+tqe8;o7Mn;o7NM!nIR%k|#RFS4pQrq=SJ5^1%b}A@&qEmazq*HaIh<2)xaP3rx@MAAXrqp?C}7+9}n=!A@aC z_{~@mPKs%#ItkC)BXcT3xOOT^xOOT=xOOTod7@M2Z^lBHTd=rF9ZIL6cFIn;b}EbT z86oMEi|~BK-GpnWR2K(3g~e6h!Qv`XOgmLdc$3;LCtN$_BV0S>CtN#KC3&J#-dm(o zK~h9JRZF;bs*do+m!wmTgohLl5w4w5T^#Hb7FU&HaTO`1ooXlC6_PpCLAZ9RlW^@+ zgmCRtRPscp>dU25aZ*G(#Z(h?u4$)igr9g>I%OyPq~ckGYo}Bf2RntuRkvbs6)C2j z@(|vrwu=eZPL&d_ohm0>JLQu+(W$Omv1I60EUqF&v{TiDYo~&Q$6k?6)e;_8ypC|~ zl3AgW+ITa>cJJn9OcB+GL?Nq1aiB8S_o^&coifE@|glnhb zgr94YPBGPFor4z@w-K(LQe7PE6c$&l#^NecOgoiFc&*wlBwRb?AzV9EOt^NcRPscp zwy(yLq19MiMT%&r{Df<#st8X#Af2ivJVWsy;o2$H#lcQtan)^DTt$j$rLf+9QxU?oQ&GZaye6HB5uUGjoN(=w>f&Ihu(;}W zEUr=x=oHmXxd^XT+it?OQ+b4IrwR$zPI)9xbSn1_EE&23i>pWx?NmA8+9@C5jX#x6 z`3VmxUPZWeN_BCtQ&?Q(!{RDZOgq&`x!Mj9uAOQkTszf5xOS>l@_EVC2tSKC>HYwuhGc*1)a z_kckEdzd`JvAC)NONJ`2xQaxycg2Kj?@9?TenWa!PI#%}KEkzks*8iO42!Go#NsMa zOlMgw;Ssf6N4R#Xk#L=5A;NW*HA$YBWodUwr&>u7?Npd>?NmGA<;sx`!hMQ&60V(6 zT^#Hb7FXSc#Z{!3c8cvAm}})~+eWx{%1*d;DvNOKluPnNrz$G3WT?{S%_BwfTV;+E z60V){5ME>)sdUUMQKd>rRQsYkq)#UOx)>{|?#4DCJSV?s+R#K5-+9*HaVYOXFxHhVqaBWnOaBWnrJsfNlR#L6ON-9!J8xeS~XU{Df;;stDJ%R7;*{%lZ4HEw!Xb$q{Kw9pO5G8VScg4zt!V@3bn_M55Xj z-63iV)<~_z8Yxn$U2SWnr8>y|+fT@wt4_kTy-~t-y)ntJ{`P-0)c(dv0qrk)b>I~> zYHVERNYVddh27Y`9{;e*I(wk(*V056*n_(4e!@7v-ZAf_D%D7$x`V1i-wu#I zov;q-eyoEcrSy1*3D0Vh!`4o?cBO-G?Mf%%+LegpiKkQ7{e8A@7_`n2h?9ca1g09I z6MDgKrD-<8ixjsLu5HmB()DOtTylTow;R#|ZcleDFS6ghcJ+R{n5wk1ONIb-`K$GnTGRE$Q|Kl7tIL~X$eriZYC>A=8CqqZfB z@G7*KIS*k46Dgvnn^MBHE#-tqf3LEO@R;I$!gcVHC8c^h_=l`xVEjB@Npl>K`14BlH%or>m*ZM>>o|- z9ab?_V-*uArkx5B-l?{0Dc7r*2-l}$BjMVpkmQM{W5wn^r@SqsNY)9JeuQhM!i2kx zBby!b@>Hn~64k!w4$)Z(OP01^$r350ZHW_J+AI@_Db=;<1hNsXZLt%sZOM{6(UyZ- zun=bpmMoDXI)U;C*R~WAeo`6YA^f!B#e{34R2K&)5SA=Gf+b6&n0Bg)@OHIbO}KU{ zNVs;YmT>JKX5N8{fERiDGDHq||DL3I|e~_nU9^tDM zFC<($rMfuSDJ)rf6ib#!G3}I(@K&|$CtN#KMYwjVnsDt@Q1V2l_C6||sv||TQ;mdc zr$U4m|4};CM0lyDb>ZnPGQN?4lG$B#k5l%!W-3gG2z;&Qo^-U<%Daee3ByimNUfzyE&! z|F?qGNvU3G9Gp&At@JonE0JQ_sV2hNL77f1glnf-3D-`A3D-`wOP=V| z@yDf8our6%Dnht+DoS|gCFxX*@QC7Z!nISXi-VoQYNcANR#Fb=?9@)V2(MP#Zo*5s z{5P}n2;ZuBA>mDmdnE5~mj3di*r<3CcX*_jcB`Cl?Us-56Y4O2!cQt*MYvD(Uv;y; zS^8-hE0)l#T2f5A)kwM84iT>Ns)=x&S1p9=ylRy^F|Rg0iI-DP+5+vQh<2)jaP3ql z;nk|=5yFFtM+w(?6_fn`vto%9*z_m)&V~J4o@+GI?1cN(b{656YFqxV#N}PXzz*%*WQ&9elbZVe>vejiu(xH-l;AQ&N8f6+JzNMq?pdKTEZi0 zyN+<}R3qU!%R+?fENhZHG0W1Pl1{afBHF1i;o7No!rPOjQyqkNDBel9c1m?|uv1vE z^b}Sskz(2@_Qt?mD_7e#!nIR&!nIRbglnfh@-w!nIRO#r1rr zow5Gwp)CXW zSjL)Fpmjiiv7<)UGmdZnr*o`iGO&_~?4#X^5MKDEOsgp2@zJsoF~W6P#R=DLFU@KAs+JVdPSp{vooXaJk}Z24B0Q>i6XE&{R9zhG z6xKWa2w%04V%n(=!ri}+In_yc)>zrB2;thPDB;?vnB<90d4DXOV(L&dr)-34r|g6m zsU~F+UZS{*@EWJeLCFU@g?|&u#J>qeifN~c2@k35Qo>K<$itKquATA`uATBrp6FD) zi4{I3{!J)SMCVkHaP3qr;Yn(JVIASAiZ>EIX@bf@$p<@ywNQmqgjLu@iZ#wuIYzi=y5xC;*SID35MHacwRQR&QQervN=bo6)u3|1{l@I)@W=L4 z)K8*eqvAPy?>0j=qMAe-r%E0q+@`p0q;8yUY#rHu&Ph4WjfAVQ8pA>)pa-wX@IH^1 z$Rt|YDu*yk`049pbK40|@=D%8c+*13I|+}fdLoh=4?mw4h?0Hsm&&p+!VjrBnQEi9 z#-+AxgqM3{J$AxZE1o6!v~O1<>OW+sE7S+j-n)(Z-FTZ!swpZgb?HMNBAE0dPh5#FSDqvZW(Y_n1S zf+KKFg_}sRV>ip{S_p6Wj^wR`?^8TXc#GoggddjNnDS!UvctE?Iy=cetX%R4;Wovi zgk#n3i;guR6^)Z<_4j0Lp|=K3b^5OsHW9A>YGDiE9ksH2t8rwHcjF?Fg{&5_RNwrK8u zP5!+#-FD44HA`Mi>RF`zB273 za+G>QCZy0v+v~{osHphUtm^Nc_U%(_c=tLC_ukYI`0HTb{*)UVLCZmBe#;p18+$=( zLFJoc8LBppgSLV$OW3#8;4e9hDCo2V+GxxM&3Y+y#G(X>KOzfS40>$>Z8hpat3j71 z(01bpXcK5@0_`-;gLZ;S4`e86}5MMvVV9#u$7?8UIgGN8}_>_zcL!~_bTUxm-0mnTs84C;P0)u?=R_06q3HNKEVEJ-~J*=fr<`~hj}Q4Z3O zT*+8GISC(olFNXHxa+QAEw)L!u3<6Tq}pp(bIPQeYgk9hu6)K$F0=)&VW$^nVE6b! z&l{OdkIW0KHaT)@mh+5oM7iL*}d;+HwgxSKKiE1b2D z#vnt>QN9z}2yK0pvkvGnXbbiq*TmU5Y?nYYFkV4uKD2T_XVvK}z={uWb{Jqav=iF= zGtNpf;Os%pd{Flrs2J)$#PME%vCx~Gg`vf*oW-EK+Bi!>1LJRTmIY1y6%GJBcbKzd z(39_QmWqZR3!`3W<9nzV>ibX5HjNH2wh15V06L%ySz`Y!Du6D47DGMI)zDIC6|@{$ z1FeKMLN`I1prY6sC^7$yP=gBs!r%6Y)7Fr*v|MJh8WwE zpn(#6$ol|e4K0DzLN`HMpu3?>DBwBH*-2~{L1R$chiD+q5j)fabwkUb9;hE$1l_km&zOaI zpyRlOZGze?7S;;A2h6ORt>eV3>RZrHVZ3;_M}+Y zYUsXU0Sl|choa#Y)($-f?SVF=T38;=-NF$TRtb$j8=(y&Q6Y3U^dfX0)HVT03mpe- zf#yM5p+(T6&~oT8=sIYV-NFt*o1yK{Ljim^i4T)TS(ppc!qIdTfci5mY?qiOGA%3& zO@*F-Wc z1RC&7Lyz$x4$Yg4228gwKh!_N!eXfCG<4Fv7^|6R81y7`7u0=)h3&?EdC)MngV2l6 z4yfCY)7fibEr@3Cttvu8r{Mh0zZMPvoP%b#(WC1utQ5L#DGmg! zDuw0HNo5w6H5JME9SjN7ehY>K8Z3u1(860SEEN~&)3;ez8FWDf4gfs?Jpo;JCx!|a z!>qe3Yyq?xS~Wd@^SaW)ngA|BPeOOyZDIBq7{mL}W9Zhk7S;f*fi^+&@3+7eWc3C( zgZql|D)b2IgH}Op8?hhM4m}KQg~p&^XwnsM_yG&chaQ6#2k@cxK@03d_Cp(>sShJL zpyR61;#uf9bR0Bk3l0QLg;qgrTPIAXlesaM`#8#4DI+a9D#QJ*b-n#bI`&@6ok5=#n8NGu_F$A z_(fzZwj1`KhtR?hdIjGz?8DK-NREpsv@E)F{``0>$=jXeG2Ea1diI0JI5u@(pA=bkiXms1QAXx}lYC zV(g*opjFVaHtY}G_ZE^C+6)ch0JVqF0BqMmljdR0e+Q02W6;&mvLo0Jx*B>28mM~@ z7U4r9vOVhGISr0L_4w{g;K6KvzS3 z(3%dMrqEr`W@yrfXfQMt8k>*vKLa0<79iW9S7!od3J= z!F~~A1ndm|{yz0S=tbyBXyZsL%eWr(jd&^a za%jeQbPPHU+6--QT3H0T8+s8MNOhs*H(+d`rO--fCA1D&4Q+((f{vSDWrv~p&<^MV z=xJ!nL@OJ&0&_n!4_Y$`4nTK7YoKM5t?UqVHMAX?GzCKd-3`sV5$FE`H+p&_vLCt? z>YIv|LjBM%^yoCSRPgEOSt&Tw1FeFVL49+qY`5Uh7HAN96l%N5%Hq&N(7cs!23iD- zLd&781y)wOGJuv8T3IW=KIk#%iFp{SRYhn`gV*EyhkBsZ_*;V|;FYUkIkXD88+vTDHNb+{q3Jdx7c}Dz91wvlXeYGq z&&QP`d9cmyN6Vq(upNaKL3^M+=m{Tk19AJE7$Rs3v>94-7a9(&fi_@2UnM#S4c!eV zZ^e+`9e|bia0p-lGzP7N+U`O2LuWuk&^+iNXg;(ZS^_-{t%Hu+07ve{*nSsh5wr~3 zJhQt$AgqB_ zLL*Q=^dhtgYP%hC{w6pD6@Txj80v$rhOUEFL93xPLjMC!K@UUQp+})7p~s*x=<0`2 z&mC}b3!J$_od5W+Nq|R@1JIL?qlZ2es6|VmyPm+r1a<91vO)Jf1q-2`r%@p^%Y@Yx zn0lYJvLLkeIh@YW)A-ka6fzhZh;!FD~Jy@!$E+{M*KBjFf+mP2Kuq&PtO}rs%RNGj}<68Y}*NeP;Rdc)Nf~ z#7{ncUC8v1@%q0Drq;g5nMXzJh+w4Ip*?tXS8N7Y5UkS}@x`pnQoNTbO4$1-B0*#2 z7wO~0o0$yki{sjhQpek0w7ifcj&u=wbQs&eDBvNZ?TaZKi!<;!%gFw65pOqc{c_RN z>H~O%l2E4$tgJd{jiqBAbSGQjM{-mlWLSwcjN=mJDCQ0p$k+mmUW z`fBvlDsqe<_7E@05|7aUw%f@4I(=asi5x~GNIdEQ+XR;A{Ap3EvGMEl%o7QbacEI$ zipY~^zs^ZMjJA$5axbPE9bYH$!$$AdIVo=JQH4Fk*7VHPzvypQAtEh^lo$(p=1)C= z2oBNr(|6oqn3TXo4v8PZGQf@*dwbHSb|lmzA`1`+C$K!QQm_`|FFkX(-$?6CPd*XG zdpNU;!iYFzP0;HOM;k>}I=`+Ev7;+dWDnBR3 z@Oibl&4L<_nFk@so^zZXGRI%dFE=l~C|tf`+DqwswHX^UpE2CzIcH<_m=PeQ29 z+;}-$xILK<%M4;$XOlQy47+YJwywp6B%$Hhhar3WmH>Cv8Lzv~OOz#kWBR^r* z4}q&k@q)44IQZ{u^VAUTL>WGmFSV{tvKUWankq+1yju>N+lKN2Ygw|z3|Kec1)f$7EjgY_Mv>NS!Ux|JY=r7@%h|s?zf?3?dIp$vXqWD zzZr^_iSy&cX!vASq+q8q^93QD=ATmdO}y5eISdshO~)f(UppTg#;@Qu^WZSFzG@~O zhs>@tKHeNMoR8uA%-rF;fKM`S9nP1c=-%OcId3pOA1;zs$Skuo70I`{0FO)JYGziY z@~q?&*lg(A+=oq`Z@!(1&V~y6Iy-ad?lCwk=k+;~B66Vv+ndbWM!?+iYs~v?{K^zD zO5(+D#OxY@Q95xAo`lib40FU~d?GJ4XJ5t_@lEE&%XmTN#l-_{%fs9fHQz?aQNE-< zl!q#}B2==(V$S05+?ULgvRgpH344i|@+jCLbLB`r3tiqm635?Kgy++5Gj*i7el{QK z^o+;8*A6^D8Q4Yaywz%6k;F%vJtJYqf?_g!(R9xws85-%sbWGRrIaONmerp%QaM211>84GbMc=$N?@A%5E2 zo`EKGR$>n`cN`r4X$BuXWWidz8DNI<%kk!?8GO9;#9DPK=4IkkELzuJpJ-rs0%j5O zhD`Lk#N3|QcUHYEwpz{enW(+_ehjghmVw%xqxtCUT~+<%#f9wfL^Kzy*4TI<-Smy- z8ObNH=@a)e=2N4Q)66_L8WmjxZ85h`<`c}bqj^g5rj2^95f1FtXwG)ys(+-~LsKmCOMm#w7jLR`IKZxEX^LgXN@K*tpZR+1iG_VG& z*i6gf(=%HTO1yX;MF^)u7FySYP`ONy$FeYv3pV%HB1UA=WHGTG%;K}M;|U>=U*gsO zIWUh*gHhRhjOF4Z<`voeN?vYOWTW`?8%&|!ocz%u$u-#He}YEuhNhM&b5fsOS-!7|iFmpDOUD!-9 zY)|FzMVa|{*`L^iGKBKXt{fa^5<-XNaa?@zkPtSjx%pEY&oOUx@tmnALijol2NXYj zRa}AF#J&BE$pg;-D>C=G_?)T1m+%cv-_COP)dCTGrsRFApdtJO>YTdqp4Lgj` zE-<~jsJ#O$Xx^5KIj7mI&qbRq znq3q5983Od=A(K1%Iq-E?$-uZBfc}LGb<+XB@0WN@fA^Dd1?KOD{&J=mwi)L)Aj(4?!xO+oz>J|{Kf7kKBM45nXOnE#m4cgsA&jq7WYdC-j~p&0hxBtK4? zEA9k9=UB_a>Q-_W*ip5S9L7ezxqT|1{-YR@{vtN_iOo4Y!_1wA|16x&bCP`p;zasf z;L`%5wqL8-dJsCQHj?vTZN7P4l)KH1v!(ATs}gXZfCU!&Z^XUMmB}Z7kloX9`+V-V z;`$~Y?#wr)^O+oXuL768FK*t&^P_p?49tkf%o}Fl=pJ)BB>T|s`W+IZwBTx-G+-t2 zcJR~;4AapM2JREYKCR}6nYi=mIMyE$d2$q?qvpz)7^c>QkQ>FgBVzPuydD-1nR?bLe3a z>iqUDHz_#=P-$+1yTohxxYapT*>(|t3=Kd_m75}Uf6qD{L{ zvI8tn+zw`$SIyzmaWh;oho@(DeA>UOXipDzJ!(ENr?1m*&*6&}cAg#Bj2bTn2P_GD ziyvV`BUl7XAJhfb3|4E-%jXjp+VIt2;_jyripK`BIGFgVQSUbiRirK!w?0Smc}|Mh z%-5TEg=e10$ME~j?5pq`Qi!h-Yp{d(5zRS)9h=OGtHjO1MSN>1pOSxk6`#g~=8>!L zNbUc^f@g%jyP@p4aHGt;b}o`IBi`QtQBhJ6e$D#1I6>oI;%iJG@gt0yflv>2_nQaj z!P7s?37IFbo!WOuTn(VBuM>|-X9`gs4*>IcIxjTW%;OW2 z#rK+c=9!0E-ra&sfz*qw2J`iK7|W>HH4kmsWoBQEmjg9s#nrgLZ%W1Y6$!QXEXAEp zs(IN0?(BQ0pHwXFdJbY&JV5^DYCa{i1|^bI2~lzr_Sj_N3XnctdecS1o`c`^<_32-ccE zS^z7f=9>%9{N3i~3s5j5B&YB3sO5Sb!QS5}VbW2s26N>?J|(*WA?=@NwrEh&a*>zy z3vtXIyZO#Syiv(BKVOK09W!&U!70(6Hqe&CC~(wVb`6ev!rUn2nEC8AxKGM5|8fnV zKXq4T|M7(>p%PqV2s;F}&h##Vm5t`ji_oQV^C8GJ%+Y@^QFz=9NUPEPtrjc~>|z3& z0agTdZnXK~A~gT7$vr%M>N!+pLrDCHV!N?RB!P(uw*~BkxzK}CUAVVGcv(#6)p$Z~Ud&y19r0g_aXF3`nnRZGYf?|+OIEzEO}MML ze+lj?R+~>P!O5^`0lqZqdj>zZ1ed=_CNDzJYr2YfBl5njh+oHReta!10IBBeYw^0Q z!TkQU{9)V!^j?cWYBVpu4w*T_thf%Z{P3iE9U8ydJboRYXgPPc`Neg71^ROBQWRWZ zJ}acw{Cp{PtuhxDBO6-HjY63DijZRSPeT0Wh-Hu((<>zO%ZHZXogvb5+x2{rB{t4{ z=X%tNotC4z7PDeG8qjXOupG4}nV&Dm`JQFYD?#csncGSbD>K_l@N#U1*)6s(Gv9z+ z7MR;_K(d#ZZ8yNm7W0gdBr|&jj#z2lumT14nNJBRGXHA@%AGb-ZbY4B<_$MuU_$0* zvDIk4eIwp8_FOQ(x{=RCy3H;{rR&T!LQa}{OEIG3%rm9@mb8Xltf9-AGtKgNaMcAX zJAjjCC7&|&hrrv1c)BN~X72Re$?89`W*&G#uwjb5Cs~cTcO_mt2SjL;3O&aAcHbh{ zXvI!R_K;v>6kBZR+po$zFREB8LK9TTV(kmvBiLlc?v$)TuxX0DC)sM#y9!l&PlT@Y zbo(Als-F-_t$#T+xN4PPbHPsavl|4vTDKy(?@+~NJ*voDB0`IGD~9xit})wI@tn)& ziqQ4?z%n!&%=g&P`Yvn60n75>s;kW2RlG4bGPnNot*l`xF4S}J`^T5&*5|)|U3a_1 z)BWTSRzK}^^A|Vq>qh-;Cu?vcp0kzh|2Mo(Ic{E7#vQ50hjfRrYZp8}XU;C;6SK>P zvj!LTWT<&Jjv1NAaLk+oE6nv}+?@paL-W}(Tq@^d$A~rkz{lp1G9<#U%;cN-gCkzT zfg)B}X_EH2??ZnRv4y3m4@KV8>7HJKex`O}c@iKx`~l05$QVX}pMNN`my zxbD`)8@>B`A9=6osCncT?h+PWuv!jWwDJR;kH~|k;NU5^L!X8tT#tj7^ZBCZ`%G^+ zpCmp#XRaydckur)-!I4M{-JqB$nVUQTOse6Qz7Hudb026)84ss$sy8RxN>}`Y|&56 zyKm)rfgP#G$rzi66 zPbOO0&P?aspH1Q2uk9EW-!zQnXZ$N(aP!>C#ruQ*+V;^^sh;k4t@ij=80YVz+3w-d z57SdKcJ`ogHh%Am7p)o7zQX5WxaUM>wc$&`Hn$Zzl(p?fe&9RL^YhYK{U1lMdVCG> zUG4~&)-fNvc{XqV*WWBL-aysDAoK0ap&y1P<#B;@$wteJ2$KLc@*!IztXpT5!I&<_j$9LJ-4}N7`89!xp9PnFY zGrFu}4}`=qhOoA|*uQq%w(h`3FHN)@w`K-Dj9AB@{I~;?FgOcQ_9A938~QIi>cMY5_`BA$xbO{6 ztQlhai%&cl0B`qO)<9ak{X0ebKgI;~KBkF}ovb^ZJ3jcsG}gUnxN-LVxvU!tl5z`B2lyY>irDzZEajrhZ3Me+74un*7tVA1f} zvv`UuoA*h);3LdZqMoK5_W0jLT>(^frzP_P;lP&|xvw#T8O*XX9hLtBJBS1A-BB9< z_`{_A7p-HbeRKuueyHzYnFqc>yd87aAJFiz;y@#x?>o@u2o8k#&4pq46%KSvH9GM) z7u0bAV^gzto=7~$v;!xK2R(+@YGh|HwnFP1elTGg}^N-EU2A-H!vgHb2y3bNQU19gd#Q zlUUgqjQIuY7<0pId}d(N5Kr44i*4-(I6?`xt;IKvWqT~c*ABz>9-OhSVOz9(@2@S# zn?*~}>b-L;$M>sN??qxAz-O#y$jIRtYlA(P%BCV|qOj}`8WKTb>himF`6brl&&u+F zdQri1*!T^0+|StD{nndW-Q2cZOc%rBm%cstQwfEil!g1s?!@O`pzQx(oSUqr@%=cB zM3!@&@jO5rX3K6}?+ zx>UAni@)`C{O;i+)_w*D|AB=3Z|><9Wp-t6)p_&-Dt%J zsID2m0iN2|iqBE(_3hrcXvJEzLhxzk`*-l^0kNAnGGFBFWiNYsEvMOr(bl52Gs{_T zIwt5YYwCLTytmf|xBeGLOfkH@7j^^}M($v}Y>&4$x`?+$*5dQ4-rkpXUj2IHHGF>B z+lz^-=PWL0?_nMeA$9mCBkKQFi~CvBe_=;>A+z7_j4oO{u`S~cZ}0G>-d@qhZgf9~ zvyCt9ocH>6r_br1;B$8U%>1#B&l+(rYqOyFm!RivG(Yt5#ewB-U`b!rCMRF(?ae&R zW?Am?_FC`t_MTm|xGiggxA!uze_&t(s4~0mPG`sYZ6BQ-x@XKe$DT2m_YQn^cKQ0R zq5s7BFdNr~QI^;<;gslym!4*AmkRLvFmJo?JnQ}9W7d84m#jDT2J4PoLjO=#uFV&4 ze#ho>T5j_8J`82IczaKM#Ck0^dV3>dd2eXUCZ`+Y(Pgq;{xD(&Vvl%xzx?y~_2)j? zHRjZC-fIbXd(VyJZKswXwia2mc1=8G?S1i6?_zr=%-zAd@&7E=pW48B-&L+C9nSTqc9g7- zPD$JE7AN!L80AmKt&hCs>BVH+dg`|*6PV6>@r7wPQqDM1Jq-OP4NK+O@NMedJd-*r%S}t{tg3I2^)(qc3~9AHg+M zWWyI9d%9z9c)A-f7Y3}hvto$YE39k{t_Z_&yxsH8-RNx#jAiGCU+{GMF?(OXW=(7G z3GbGx_}HCi9`SUq<+hz)f8^;cO7U#@>~U|~)U=(?UC-IvkU9Gu` z*2q)%bxd}-mU~}hSrtxRSLyVj8}myZadsKzmb>`a62sGb0H@*V&5yM1X7Pe)BR$*B-zyrk{g%@sYb;eWFb`Me*82xUF!%r(32 z;u8bO7>!XV{uy%c?7g10JNWRm6*zA^6W2QLzF~`V*#9nRL!0wG6Yq8o7e!rboxU6H zc19-h-UB;ITYtw`!Mhj{aScDK*prur&YiY2*!Hev*xAos-81F@;={i5bT8zd-ZM{o zy2s#L{@aG&!rRyQ13dw2%Gu~nPxn94d9QC`@mKD#p6<^^^4<%--7^M{yJhV|*`a0D zdtUS`@j0h6OWxlj#ALzD@ zoc5Nre!(=a&$$Ns`=L9b&G`KspMSq3;B&tBIBO6UiM#P%Bk!WC^9RGjf|S&uIeXLkIK+tz<^)9vd;x`^2&iW?MhCW|xrpVsVY-MHBh z=~Ikr1lv3x>z!DB*K$uU3%D@QB^AytOm|%c0N5727AHk?2c95IST@qz#x_6FBVy5y z_l&{)-F;^QxLY~9q|H6f=bVX{pRub_{<);>2|W6r8IBWjikt$)$tI@F(2h|(%ZIYE z6ils)lG(j6dV62PeEB(U6oz0-@c?lCb#C9eHkZ}! z!f!}ezh-^k1!pFvdS=_~VyP&8!< zOhtdzSlFtmnR~{Z;jDmRw=PjsToQ5KczL`)Y-63PlYfLNP+i|W(F*hp1Iv&Eq8TAf zVuH^^nUv|W-lS~L7U7w=AD)BMb|L%b;j_@dUKIH3VQ*WCqo_^H_peW_aQZ&*e04n< z@)<55XOhvEu?Y=K-ZN%dGArO{py-I|-C zqU9&yLdqvdQ;bZmIbsdZ$xHckN!v0EVk<7#T!b$y=`%BBq|ey|E;3q7KKD(AAs(O8 z^sV8e1EbE)KnCkM;7gpIbPkw^!+oL7|Fbaa=_R-%6%1YP#%D1X{1m@8;PbhMS?@7? z{tUl$Kj@zd>hbvw#9!>&2lFoUFZdP7+Ea!P8}NJfmzcw$Dfkt0ftVAb1xwc_&Iw{Z z5c9{^m;?IfgwcIhd_N}S_hBmQn~;~?hnHKnSIztH<0~fH9Nunm7H_QX z^5v4Y*b?(U*YXKtQ-}Q_d*KB_0 zzIm0-n!>ftT67>emzC9oea@ikVdv{Ed@g+0`F(UC=(^iEGZP7MX-V6eF)Y8P@NVZB z+;zQ=&%)Cu#TnyIQ0p z&))1j4feN*<{#Jb>A9#)q`bG}F6SqOTVPKm?5%|2-mBzJ=c#wi3G4ZM{xkFT_52nm zZXaGAewWjaHov^$E@zGVF6S3G=qdE+^d*n^(RzG&vBCTXB~pin7w%2Ux<9w)&if~r z*WS+yDnwd~dTk$HDoa5c{^FZUjwDZo^E0&J`XrXWNX(V6`_m~H8d!cgF7x6nI-PvC z^KuO3-^W!uBe{1wCoS`AsTu3N`Zve!?Yni|kIcFbE=)21az7Stq8&pw;2k{{%x%E? zlqu$l4fwj_UGsqrc$xS!^Q{fMU^b4Bym?Je1U>(o?QZAa(fcsG{!Ix!W4vl=?{N-6 z%R(-gSaPrPQ@But(u>Uds`!e`S&U2 zdsTQB`mXs!72i1z#zk{|PTSW@+AiTHkG=2Nau>302MnxCMWW!QaEW_^xK(d!!YB!Y zN1$7$A2i?Eh&M$K{&LI%7zNR{TOQ=OSFFSIKNS~Rap}rMvWU+W^D6r8gkKZcjch)J zO#Y5FbGR+teC|PhWx$4+Gm2T#hFP)+%F#g^j^iqM$T>%B|6emDhOBR<#BlsyGo=kz z6PuhV`zFfhfQfQd4=$DF@=bhpK+KjlHCsk8TSiCkS{1>}DyDb;kzYK}{;2zT=0?MM zeIMEQ=;0~bhNZi=6%S826kKKdQ_9$!^`ke2F2mh7Zi*ifZydh%^x`Xn3~@c-uj16r z!qhINcToqs=S3TCrE+j9bq-TK?tTKt$sAfI?xTKg#dP__1rHwP z!VCGUcn}#pN2X8fyXAS>(`Ng_o-t8871d5e57CgPaCP)d-0Ccb2Ip_-y8{Ug_c?v| z)feh6q*ksQ_ijj`&^*7BVNMalIuq$*8(GvQ=I(!_BmHoJu}#EljZ=6Q;Fwjpt-`q& zHl6yE^`0Ji>-t4WZ1!g(y}hRWKlu2-$n5o9!^Oizg;U%&531?^sHp3=o?hF~qPAQ- z8Fk_5#fH-)jMj>Zub+xu9l_-e_tXE4&&3s&@}qe8$ia=;&f71Q*>KY)K2OKz0B&v$ z48?)>;~mBC&6~aRcYt{9sQC23p@U@4{2RxXo4f z$$jH1?vocKjGqUe#dwL!mlz*$TPwy#+}esu7a9_16Zf=TxNBoLO<3W5eLZ0Qhn%7} z*Uv+Oh!`pnPqpF+w(m(6V<(?~x43uU@$E)W?VlNml1S5DDpYgqX1O8`*jLY!b z_p1HZto|+Y^KF>D51P4;;%l+z%#Dxo=SM6S1$T(Ii#Z3D{4zU$Z?5r`-Bm$8f5e$! zf9NxFTaZ63+O!>Cu(g>L+fl_U=E3b)o70H>eE%a`=s)G@_Wf11@ENmrJ36pSgx^!) z-y!^;GW-K`=3@v4MfiXU{~Y0;%J3HRHWA(=!q2Gia|r)fhVM6@5@EjxZ&BgL5PnpK z?=;^Q;ngC1rwZSP@I5m89rJS$E*0VHRd^M`D`fb3bNmj3i$oZ&`-JuWs}aUKYGM5~ z<_#iTD8ge@cml$Br7gl&n%fYbIYWdkDm)C~Au>D}TzpH!#g~3KiNyCVx#p1__^$DD z^ZX8;J|-Gq4Z$Iv*FQlv){gpr#eI2r&Bqt_oioXGZ)&-bO+t1;LR17P5|R)SOG+#i zOC&-qttC`7YDsF1r4kaSv?ZZhu_i??Dw^0TbcvtR(vn4~ohT~W@P6ig6Vl)Nyzjq1 z&y(kSXXebAnKNgbGmFqF2c518oC>*Tw}se=jp2}m*o5rGa~FaGZgZAOb>MRg#TsGF z6Bmir&O3mj3~NFQ*93uU0=33J=bekt^=wt_R8#DZ;-*^hdcK5W?B_mOB-|UUP*AF; z*eyz9&&A?>he>s^YB!C>asFcQmH^R~fGIlhDty!yOVz3y*vCH7< z4CjR9=-Atwyd2UthxaXmptx|za+G;$Wr3D5hu&!LgXhn=Zli^~bGbN*+bc;cgp;p3 zAmYPy842FHj0%Jr)b^?i^2Q*o?Qt}<} zT!EU^9Iz5S`-`JiqAv$|vP#|NMJwUroaC!3F(;cj`9sL}7IXfGYSVf=A6SJ!B$_X* z5_?E&Ft1!K?pZlZ$4=VBtDk_>VjYKVzywU@j1BPX0{OxQG}@67I1a@5lZcH#w2;Sb6sJM4fNVfk za%wgp&0L%f$O9~L0BO=74Ll?VkU3`0O=7b(>8A3DFGP%Zg`KyG?(_eC7iy)3cMIj{ z^J-?pwt1M;*P~~(={ll1>i4EYH%;y8o2cnnG`ji|zz$;&%%QsIXk;uY%`=_#U{ zx&KZ~l-R@0yM=q$_L-2`Sz%S~I+t6a@Tk8~>AouMY)Nlc>2Khm=$cs48&w+S#a-uQ zNq@}AyCGULS>)k-M}oP1o>(BLyg8fm#Z1V8|Ccx@@i!-b3C26c1z+MA&e!iio}$C5 zCLFQJaMu|uXueW;UdS6`e31vkvj^vucBmrg!wH+95dfZoUe>CTEj$n)IAbzyj~Fku znZMtoB;*{Yeuc^NG;jM#d@e)+58N-BBl+%rF-7SAnGS8)ln<8)$F&EAt;pfV2XPjp zniCG9wO>$L=BV52jt$O2v{a6zdgjJbC(Iu^5`V>ae&X=JBO(R9ASzQPgWuh*=!Xv4xhb zd4-~vz9;IHZQ{5>2%je-%bkrym~vkZD5|aK#_tq~*Ff8yT9yT>5>Wbk({!1kAJx|G zc0~LjzT^f+Ytg&&z@va-1+}sk3OyOBe-BylX?3!^Ipi2R7t2Yf>i?LEHfGf#j5{H&=|4kO*_7HW)oF9ux0p3FQh8F?={ulY zm%zIwkt1Z%vl#A!k@JgRw)LnOTC1D~o_d*;bqdX&-~ug6YyLEv|6&T7f4#P?xYJ^n zn9dEpdpVRL-vMe6pbC4|Lhbqvgy?{*ve4QrODChg7p3*AUVj^A#-lmebLcs-Lfqu< z&x!fs8uvdB{x+M}orgIVo6W^Pi+2R3w%Y}C5y3^jA?d@HegjFGbHpVv5~SXA38%(dn9p1iQsCh8xyxX?%^Xz< zP^jio2;OYIQ!2bU>y_c0}%_|y9s*l50SAIch@ekEq2GbdGou9=)w zDaJQ&L2YHMgjGt+DmFd#id*`TW1*z1Iqnd-7_st&9`Vb_ z<(#8943zy)M2fC_X(eU8EBq`wRS- z!JbdV7orCjKM@^3t7lKdQ)edy7%i%@J#>5DjSJ0HOC_uaG;0A8(8) zcvI--AV1XJVg@p)9t6lU%Z9Fr&RLbzj>`SnTTm>TnJZ{JB-oe8U7Y49qSoRco=LP3 z=lvWcDJ#=Wk_)LjP1ZQ&l*(UPQ#iQmku|yN?~g_!r0KLX9H1vC33Gy;%mN`oX9Gb( zy|}x9COh>3B#!0oRlENVIAVtBEb%RB&PNU8AKn>-We!@Qr69*A!$zjWC_r@p!egrVTEv0G)#w417j_A#X}B3}t4UV3?sivk9%j z2~2BeRCgMI>50;+L-9FNcj3Y3RLPa$Kpd`>9OH2=^dnA!c5JFh!^4|WwAjwMO=%XK zXU}Fp8_gljfOZUj-;8FtHb><$KjlNX{9itVwK>6+dJFM~IoFMb3sGXW@}Ly8hF;`J zU9lW1@>E>Wk^k_d0&$B3B0W( zt+yWgU)fLP?2kLpbAApReArg;is7fWmHyU=5Zu5VXx z!H4{5S4`JbK7fn;Fw-`{^p&!`!Kx>GEtuk z2aTi+19)C9fZABH_#@<5zc&DZTDGl#4s6hq>Vs!pdV+fWIj1Ke6Zk|=nr__^K%s2g z1uo6bsnm$$Bgh(MZ${8`dj7g5q_%+ZwFs#)EZsP=7j>ZXaIAWeH|HB*820y~V`44O z?G06!!=Lx2@wS_sGJb&}ao(B|(*<*fvAacLejtI7l!z!qK_nf8hnE_qv?oWK$%X6p zC3}4*0H62b%TbuxQjYCIQx&iF`4?2Ma)0__5S~1xFLkkA9u2k0mDezcqP~zo`1<|8 z>Zv@h9}TzqwZG0@bK36rqlH)|%gc2d&Wqz~JeSnc)K=%b&65V6x+r z11Xs7`*Yk3a^z+)ApcbMjiEpzp}w-P@A0@8N~A0OURq(0_D&4B8_)Lx2wa1H>@bK% z8}}orjBpv}$B`2keoOT^dl2=cPx`UVNosFgqu>#3F{-8$>79OcTK$o82cy+73Iqox ze&MTwX%HO4&O`8N&nt&O-GdZEXuMkc48`XP7Y{|*5A6B|2EPSoduco^@5^yx$d3n% z!bnm%VHkZZhH~{Vnqds-tMzsdC&$w35U1i;RBy0QG9nZMH^cotw<5iXNH0l@oVTk zcuuN1-HPJFBdIO_5=XCzGi*DWf{forY1Kn`;Ak2|I{=c5={Pi+MnZWx$I~F2c?txy zdl<=2on;LCyW)7T#bLe^54PyT{s|ySJI+dg6>{M_2^bT2Wef#1ei*6Coav`KFs=(Q z)Jut(pkXlnjC|F{LKe{w<@W5FNIkGjPe>#tj#RyL zMS;6(is1g6P!5}VYjV67HI2%nfUzA9V~W-4@d*|wx;cR^;?BbHiAaU<&586m!aNz1 z$O$SlcM?XigO5*w2?AZ;!c?8$$!{UGgb%!hvI%_dE&ADEQm>cFvDU4CQhgf`KIThr zL*%e*OPE4-%5|Co;(o{brce(uM`%8UrQc!fHkIDBPLHUomF%rO+h;5@@}vmrvUVC7 zL?bp%LpSE|xM?)nW-Nd$1h?geF>u1Z>B(-1P$LzO~A zz03tO;0%IHJ7+;RM=Ko743-d~{kB{Vn@R3AVKuPk9(;HPIhj*uQfmS;S!#UB<+IS0 zCv5#5BtN}}hE~u1@6nHRBAj>4qV^(61Nw}IBm*c|0l}~PlIJFaj6PhD44sDs#B2%z zqD8amp8lh75YUT1d;rr4!j@oRxc+_EL-?C>ltJ_1?sF&!i1Ssls1^S_hq6Q$o;()> zY0N9y>m-4rW6{1^{gj1J{)ZnBeFQhWecse&(kfM&L{?*a=aM=zi;BA4?Qke%zoPvrI?=g zRVJP#Sqhq5;PR!k97I_0Yg5FQ#fOKRgaYj1E z_Xby`qibP2FoRavdZNBkimTgdeaqs?43HVvS3`4R&Q?=zV`(r7q1A_Qc{b=Ovu$fw#~wL`g1@QW~*87i`hyCV=v3XY<eF%7lpP@6VrRae!m>dNKo&}O9dc-+u@yknh~rsgfNy@v zp`K8zsNIgEHo@(<_nL+R8#SA-&@JMDo6#NM-wex|tqNf_9aW*-+RrFhEas5UFpcqi z?lZtealjVXJMY(CT63dw4Mv1KKF3@^V|@;$xW)ya(-(9oh))fLWlY}%%ZR7EJ1E!V z3zUQ1w$d6J8>BF~@$XxyiOujJjZ`I_cwRDM7)h%jGCesW7w$w;zL86THjQgQmevLN zhsSNB&2+XC-^``UX4!2Ne1g{j{G4`NU! zK0E?|zB@6QPzgI}x6uS78Xe)DHBm*4`RhUCi}*{@E|BV8M>Jwgi2)sV!Nn}*fZdQ` z3~o0};zEwd11fNP9;Om|JbBO+pj|%LJi9|37HrF(=7UGP6*BP1Ixf!#3F~uclETFI2$@rm^U)4~g^lXm0b3-Yx{U5OaOxg)J95$<$Rw2H9&p1l4%rJ0 z152;kSb=$mXej*_pfQK<=a^M6eF62h2}dPGgZ(vSm5X8W+qCCh8vd2DmDNDh3uX5>+L!st?rnq^xkw0c^2|i zBN`0fJp#W1jB=E`Uuo42+Z5PaQTNz4&L9W>LSz`~;{qM(Pdswn>~WPR{ujY`TVxCt*LpZ2GkSj`EiK=NU2Ew%#^R&W{&h64hpz`Q3o1%(@{rTQsmw5v_^jg5S8xQ*tOP37J z_z^su%3u9ReFSU)5GegnLJO>hp#o1kLoLkyXJ9G?jx+p+zJTHj`w32k>jT6M2AoCk zV;`rUMLB%Svzm|d6O5-&PtAd zsD2x5g(=%;Vw0>ux+^<=9;)L9_Wv0~3FU~NAtJEfKSL%KwniWCZ>E0OcHi;~rXYqJ zT!4;35cL9l2#{B$o^$L)EVRq`+(oEA%;K-`BXju7ukdT;`=K$g!6Q!k4P%ex%HJ>; zI2e~OA)olxnSJ!~5_KhaKi<_vdU5^B^b77vU%iab-9}$ zu8t!YmXZhXcAN?DP)^eQzFYTxG?c~H5I8~p*3 zk6HeMTH0)Gsmmv%K45N4B649CU>3gb4O+iZCsG5jG4tPQ4o*L`}50|~j6!0XAE zD-q8`xch;!GmUun1DdRsGk;QZtMWz}#hm|u?9H)%Vri~|s}C)MUi=UXsSYY-#~u}M z!#p05EtWRzAAuM)yz>#-3FC{8z*?7i)ME=X`N6Z`Esw#+d+THk6#<<37X%94z+VuR z-S=vhi=!I>1SP1IGrwq&^Ec>K`-;-{T*8-zL&a)3)(O zzI+iTqBAGq))<~ws;ou;=eegQnlm}+8FDXh>J3@{?yfuoDiT6WDPDOyAg_L~}I!Th! z9io^a`kXm0^$>lW0LwSjvjKct>>^zR1Smj?RM7&+=BD#$wW$bud}YW zpG;WRUT;o7P#_92;q|Ij_i#YSLbjU1<&Um?Kuf2|TbqS}d~VS@q>3 zwSaFR`_ilne6WE$h+x3XhH?gs@QsFYkg{5hBjNt^5-{+Lp$cyr0QwGT48C@mr?*i5u#YrwQh;F%X zx6_cj?_I!JKeBIA83+oEYAXLwes?ppGmIZKL$w|pv6S&RwwD^i29JDfQ!$ZL~mrY?h{hOofZ*W?3*%G@< z`OT#hVzZ3h5pDw3h_`Uc{6Fwbm( z(SO0YEr1D&WqfS6F0OBSh**evwL!Ue6=tK4{6j*yRQf7`Gu!&f1;X_^M}$#uD`5ig zJtxDhLY%=C);Ru$y~g9_{MNFOz@AT08z2@z<{SRf4sSS{tJ`7*5Nz)lAcF=LjF7L$Io7{0RaWihM4M79@aFN_y z=WxplX$3lAguThmq&xE%!!E;X2Cvj~%Ep$zY%hm)z7dOZpp6p7zP@v55N>!St9l-9 z*qa`{9-jO74fW*3(XDsvb@p}B2=xU@Zx;i=CXk`80acd@UGhyVm?nzQWIJ2)yg=DW zQdC>>SDoZziK7NPyU5Y>3H;=)@@%uY5mkmTo#oV;n*XfEx=aMA+jqh zO>zjP_%B`u066bOAz;sGd^JRV3uk?2H`yDzqmR0QWxi$K?$8Add2)ADaO9QUWsr{t zFkY9TowwrpJib+BIMpYr=C5`^ezq(PJ_)ZD`@=W8%V_BI&Y@_diW5R*p!03h%X4xS z7%6u3{S<-2cxNb@@#M--2tJM}heQzervI2A@ucfGQy*%nT6oRQ1XP_%kdMe{ z$9+0eCrclHw=IJzQ z#*2DMZ-+gAD#8_k?jv=T@i@L#1}K=3UUIwVuP8!R$LjZsw$`pcJvUyN*6Z1G{-qHl zhtqmP>mm5rTe{Cr`1r~+f0R_ee>nHy>*B?E-0R2fOoJh(hU!v-;(?Ut(5l+gc(qsy zkJ*_PpsvUB=N%Mf&K|WhsUxuUb-GNIE<}0_j!qW?=04;^9XMC{I^^F*9$ya>6lU0qL!xAB?B-020^fYb`=Y?zh&o0|JFE1DSlXnt zkoMfHk8ENas)jxWub9*vL2YG@=p$DN-<-TFrWsJ9UYPpuCY>|9@lCXEkr5Alcc~%j z;9H9Cdamv(m-u>auLFL}M+0BzVgb*u0pEk~6!Xr0GF>$D^s+Eh@ftf5d10doOs|G& zXr8(?(Ht8s1NFY;lU|@K2_N~ILRpg7&((r*cYUn~`S`xg`v%MBzBvhXz)j8?_&ZH3 z;Nxn*$K&h8mxjoVz6m4hfR{D-7kFR|ct?Eio3{*=Ukfo{1|A)FB>8Ebpr(Xwfzr$e2w zgH-Aw%^obc6r+XN*C_*C)I3`#4^logYE;LKnoKkPc-ni?m2*df)qXag8!bnWm~0Lh z1MfySn^P0zKhkqi1fED}x=n}c_6*d)4sl39{vD zK<9~S>LSaFYWp25)zr?g>V_94Z3gd@xNerY_^mHc4`^zDrTeibRXaC_^UZ)${UCyV-PBGHC_oq27RfY@1TXQ~;q4lTX&dPfcRd3yT&TVm} z2yV{-4p<;Vy=n@2qhJ&IufxClxCN7rkL~)1D$|iRylR1TY`OuzE81juko$Q{*(RjP z-;y?GFOVKq=JHk2WM#g;TweFbruT&d@E}S!_Mp5sf7$|^2gJYs(Rcp;s^OY;=l{<} zu5|$I|4%7^Ro4Hf1LlMRdCy9u^S~qWRpUD!Xsq%MryarS{sqTyu}YRK(Mn6$c+`@_ z?gIXmaFj~^vP4V%!f7h0JD??XT&$AW2eo828;>FB@wJxp;3y<*hZShaVFl8H65+pN i=+3YL*e?7V#>J{qc1;pEjw8gA%~9%ek<*ULmj4G@L&+lm diff --git a/apps/predbat/prediction_kernel_lib_armv7l.so b/apps/predbat/prediction_kernel_lib_armv7l.so index 2b2c3aa57886216e4055fca1436461daaa3bbbf4..47f6f9624bc65544e941ceffe4f09651c261e2ad 100755 GIT binary patch delta 24239 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 L9pxW??&SXiC()yF delta 24414 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 P%*V4X-V^=%&lCKA=k>uk diff --git a/apps/predbat/prediction_kernel_lib_darwin_arm64.so b/apps/predbat/prediction_kernel_lib_darwin_arm64.so index 35ba000fc4bffa081a8cde44e7b8436d0e3f3fd7..e422a1c7c753323c33afbb80a7ff2660854629ee 100755 GIT binary patch delta 36569 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 nd&+^QCw=YHxzE8lyI(%n`O9rD99r7_{>7yX diff --git a/apps/predbat/prediction_kernel_lib_darwin_x86_64.so b/apps/predbat/prediction_kernel_lib_darwin_x86_64.so index 2952311a6ad44107d23cc9bcffa7e53feeed77c7..7ffdaf0309992a88b4fd6757d7c4568042e70630 100755 GIT binary patch delta 34740 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 Dqv-6* delta 34874 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