Phase 1.1 landed sharpe_per_bar_kernel.cu + launch_sp15_sharpe_per_bar
as orphan scaffolding because the val-side sharpe was inline in
backtest_metrics_kernel's 8-metric fusion (lines 208-211, 277), not
a host-side loop the spec sketch had assumed.
This refactor splits sharpe out:
- backtest_metrics_kernel computes 7 metrics now (sortino, win_rate,
max_dd, calmar, omega, VaR, CVaR; remaining counters unchanged).
Output stride drops 14 -> 13; shmem 6 -> 5 reduction arrays.
- gpu_backtest_evaluator calls launch_sp15_sharpe_per_bar against
the same GPU-resident per-bar returns buffer, once per window
(kernel is single-block by design; n_windows is small).
- Annualization moves host-side: WindowMetrics.sharpe =
raw_sharpe * annualization_factor.
Atomic per feedback_no_partial_refactor: kernel split + offset
rebase (every metric below sharpe shifted down by 1) + the lone
WindowMetrics.sharpe consumer (consume_metrics_after_event)
migrated in one commit. No parallel paths.
Output value of WindowMetrics.sharpe is preserved (verified to
1e-5 relative error against f64 closed-form via new oracle test
unified_sharpe_kernel_equivalence_under_annualization). All
existing Phase 1.1 oracle tests still pass; ml lib test suite
holds at the 945/13 baseline (no new regressions).
Eliminates the Phase 1.1 orphan launcher per feedback_wire_everything_up.
Sets up Phase 1.2.b cost-net sharpe to also use launch_sp15_cost_net_sharpe
on the cost-net returns buffer (separate task, separate commit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>