feat(sp18 v2 P1.T3-T6): atomic delete SP13/SP16 hold_cost_scale chain
Deletes the entire reactive Hold-cost controller chain from SP13 P0a / SP16
P2 / SP16 T3 atomically — replaced by the SP18 D-leg structural opportunity-
cost reward landing in Phase 2.
Per DD7(c): observation chain preserved (slots 380, 382). Slot 380 becomes
constructor-init-only diagnostic at HOLD_COST_BASE=0.005, never updated.
18 consumer sites deleted (8 from plan checklist + 10 from A1-A10 audit
expansion):
Production code:
- 3 reward subtraction sites (replaced with Phase 2 placeholder comments)
- hold_cost_scale_update_kernel.cu (file deleted)
- HoldCostScaleUpdateOps struct in gpu_aux_trunk.rs (~120 lines)
- launch_hold_cost_scale_update in gpu_dqn_trainer.rs (forwarder)
- Host controller block in training_loop.rs (~60 lines)
- Slot constants [461..468) in sp14_isv_slots.rs
- HOLD_COST_CONTROLLER_GAIN/FLOOR/CEIL constants in sp13_isv_slots.rs
- state_layout.cuh mirror constants for [461..468)
- build.rs cubin manifest entry
- 7 fold-reset registry entries + 7 dispatch arms
Tests:
- sp14_oracle_tests.rs lines 2173-2926 (11 tests + helpers, ~750 lines)
— these include_bytes! the deleted cubin and cannot survive
- lock_sp18_v2_pp4_retired_chain test (deleted, no inverse-contract
replacement — locking a deletion is pointless ceremony per user call)
Layout fingerprint: range [461..468) is RESERVED gap (SP14-C.1 pattern;
ISV_TOTAL_DIM stays at 507 for checkpoint compatibility). Layout fingerprint
seed updated atomically: HOLD_COST_SCALE + HCS_* slots replaced with
RESERVED_GAP_461_TO_468=SP18_P1_RETIRED marker.
INTERIM STATE: 3 reward sites are now missing the per-bar Hold cost. This
is forbidden to L40S-dispatch until Phase 2 lands the
compute_sp18_hold_opportunity_cost device fn that replaces the deleted
subtraction. The audit doc records this hold.
Validation: cargo check --workspace clean; cargo test -p ml --lib passes
(state_reset_registry::every_fold_and_soft_reset_entry_has_dispatch_arm,
sp16_t3_wiener_welford_slot_layout_locked, sp18_combined_slot_layout_locked,
sp18_shrink_perturb_slot_layout_locked, sp18_fold_reset_entries_present —
all OK). Audit fingerprint: per-bar Hold-cost subtraction sites count
13 → 0 (smoking gun for complete deletion).
Plan: docs/superpowers/plans/2026-05-08-sp18-reward-shape-hold-attractor.md
Audit: docs/sp18-wireup-audit.md (full A1-A10 expansion + post-deletion
fingerprint)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2229,32 +2229,8 @@ pub(crate) static DD_SATURATION_FLOOR_UPDATE_CUBIN: &[u8] = include_bytes!(conca
|
||||
/// launch (same cadence as P0-A REWARD_POS_CAP).
|
||||
pub(crate) static MIN_HOLD_TEMPERATURE_UPDATE_CUBIN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/min_hold_temperature_update_kernel.cubin"));
|
||||
|
||||
/// SP16 Phase 2 (2026-05-08): adaptive Hold cost scale producer cubin.
|
||||
/// Single-thread cold-path kernel mirroring the SP16-P1
|
||||
/// `min_hold_temperature_update_kernel` driver pattern. Reads
|
||||
/// `ISV[HOLD_RATE_OBSERVED_EMA_INDEX=382]` and
|
||||
/// `ISV[HOLD_RATE_TARGET_INDEX=381]` (same input chain as SP16-P1) and
|
||||
/// maps the overrun into a [1, 25] multiplier:
|
||||
///
|
||||
/// overrun = max(0, observed − target)
|
||||
/// overrun_norm = clamp(overrun / max(target, 0.01), 0, 1)
|
||||
/// target_scale = SCALE_MIN + (SCALE_MAX − SCALE_MIN) × overrun_norm
|
||||
///
|
||||
/// then Pearl-A-bootstrap + Welford-α=0.05 EMA blends into
|
||||
/// `ISV[HOLD_COST_SCALE_INDEX=461]`. The 3 consumer sites in
|
||||
/// `experience_kernels.cu` multiply `isv[ISV_HOLD_COST_IDX=380]` by
|
||||
/// `isv[461]` to scale the per-bar Hold cost when over-holding is
|
||||
/// observed. Cold-start fallback: when slot 461 is at sentinel 0.0 OR
|
||||
/// outside [1, 25], the consumer uses scale=1.0 (bit-identical
|
||||
/// pre-Phase-2 behaviour). Per-mortem of train-multi-seed-pfh9n showed
|
||||
/// realised Hold-rate climbing 0.25 → 0.52 with cost magnitude ~0.006
|
||||
/// (~100× smaller than per-bar reward magnitudes); the adaptive scale
|
||||
/// pushes effective cost to ~0.15/bar at 100% overrun, competitive with
|
||||
/// per-bar reward magnitudes ~0.01-0.1 but well below SP12 cap [-10, +5].
|
||||
/// Pearl-A first-observation bootstrap (sentinel 0.0 → REPLACE). α=0.05
|
||||
/// mid-cadence EMA. Loaded by `gpu_aux_trunk::HoldCostScaleUpdateOps`.
|
||||
/// Per-epoch boundary launch (same cadence as SP16-P1 producer).
|
||||
pub(crate) static HOLD_COST_SCALE_UPDATE_CUBIN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/hold_cost_scale_update_kernel.cubin"));
|
||||
// HOLD_COST_SCALE_UPDATE_CUBIN DELETED by SP18 Phase 1 (2026-05-09).
|
||||
// See docs/sp18-wireup-audit.md.
|
||||
|
||||
/// SP14 Layer C Phase C.6 (2026-05-08): h_s2_aux RMS EMA producer cubin.
|
||||
/// Single-block 256-thread kernel computing `sqrt(mean(h_s2_aux²))` over
|
||||
@@ -3661,9 +3637,7 @@ const fn layout_fingerprint_seed() -> &'static [u8] {
|
||||
KELLY_PRIOR_WINS=454;KELLY_PRIOR_LOSSES=455;KELLY_PRIOR_SUM_WINS=456;KELLY_PRIOR_SUM_LOSSES=457;\
|
||||
DD_SATURATION_FLOOR_ADAPTIVE=458;\
|
||||
PLAN_THRESHOLD_FLOOR_ADAPTIVE=459;MIN_HOLD_TEMPERATURE_ADAPTIVE=460;\
|
||||
HOLD_COST_SCALE=461;\
|
||||
HCS_TARGET_MEAN=462;HCS_TARGET_M2=463;HCS_DIFF_MEAN=464;\
|
||||
HCS_DIFF_M2=465;HCS_PREV_TARGET=466;HCS_SAMPLE_COUNT=467;\
|
||||
RESERVED_GAP_461_TO_468=SP18_P1_RETIRED;\
|
||||
MHT_TARGET_MEAN=468;MHT_TARGET_M2=469;MHT_DIFF_MEAN=470;\
|
||||
MHT_DIFF_M2=471;MHT_PREV_TARGET=472;MHT_SAMPLE_COUNT=473;\
|
||||
SLOT_474_A_VAR_EMA_DIR=474;\
|
||||
@@ -7845,12 +7819,7 @@ pub struct GpuDqnTrainer {
|
||||
/// boundary launch (same cadence as P0-A REWARD_POS_CAP).
|
||||
min_hold_temperature_update_ops: super::gpu_aux_trunk::MinHoldTemperatureUpdateOps,
|
||||
|
||||
/// SP16 Phase 2 (2026-05-08): per-epoch adaptive Hold cost scale
|
||||
/// producer. Pre-loads the `CudaFunction` handle at construction
|
||||
/// per `pearl_no_host_branches_in_captured_graph.md`. Per-epoch
|
||||
/// boundary launch (same cadence as SP16-P1
|
||||
/// MIN_HOLD_TEMPERATURE — same input chain).
|
||||
hold_cost_scale_update_ops: super::gpu_aux_trunk::HoldCostScaleUpdateOps,
|
||||
// hold_cost_scale_update_ops field DELETED by SP18 Phase 1 (2026-05-09).
|
||||
|
||||
// ── Speculative inference cache ──
|
||||
/// Cached trunk output [B, SH2] from between-bar speculative forward.
|
||||
@@ -15793,89 +15762,9 @@ impl GpuDqnTrainer {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// SP16 Phase 2 (2026-05-08): launch GPU-only adaptive Hold cost
|
||||
/// scale producer.
|
||||
///
|
||||
/// Reads `ISV[HOLD_RATE_OBSERVED_EMA_INDEX=382]` and
|
||||
/// `ISV[HOLD_RATE_TARGET_INDEX=381]` (same input chain as SP16-P1
|
||||
/// MIN_HOLD_TEMPERATURE), maps overrun into a [1, 25] multiplier,
|
||||
/// and Pearl-A-bootstrap + α=0.05 EMA blends into
|
||||
/// `ISV[HOLD_COST_SCALE_INDEX=461]`. Consumed by 3 sites in
|
||||
/// `experience_kernels.cu` (segment_complete + per-bar positioned-
|
||||
/// Hold + per-bar flat-Hold) which multiply
|
||||
/// `isv[ISV_HOLD_COST_IDX=380]` by `isv[461]` to scale the
|
||||
/// per-bar Hold cost when over-holding is observed.
|
||||
///
|
||||
/// Why this kernel exists (post-mortem of train-multi-seed-pfh9n):
|
||||
/// realised Hold rate climbed 0.25 → 0.52 across training while the
|
||||
/// cost penalty stayed at ~0.006 — ~100× smaller than per-bar
|
||||
/// reward magnitudes (popart=0.97, cf=0.65). Hold became
|
||||
/// effectively free. The adaptive scale pushes effective cost to
|
||||
/// ~0.15/bar at 100% overrun (observed=2× target), competitive
|
||||
/// with per-bar reward magnitudes (~0.01-0.1) but well below the
|
||||
/// SP12 asymmetric cap [-10, +5] so no clamp interaction.
|
||||
///
|
||||
/// Per `feedback_isv_for_adaptive_bounds.md` the bounds [1, 25] are
|
||||
/// Category-1 dimensional safety floors (NOT tuning).
|
||||
///
|
||||
/// Per `feedback_no_partial_refactor.md` the kernel + launcher + 3
|
||||
/// consumer sites + tests + audit doc land in the same atomic commit.
|
||||
///
|
||||
/// Per `pearl_canary_input_freshness_launch_order.md` this launch
|
||||
/// MUST fire AFTER the per-step `hold_rate_observer` chain (which
|
||||
/// updates the input slot 382 every step) — same launch ordering
|
||||
/// constraint as the sibling `launch_min_hold_temperature_update`.
|
||||
///
|
||||
/// # Pearls applied
|
||||
/// - `pearl_first_observation_bootstrap.md` (sentinel 0.0 → REPLACE)
|
||||
/// - `pearl_no_host_branches_in_captured_graph.md`
|
||||
/// - `pearl_symmetric_clamp_audit.md` (bilateral clamp on
|
||||
/// target_scale + post-blend)
|
||||
/// - `feedback_isv_for_adaptive_bounds.md` (bounds [1, 25] are
|
||||
/// dimensional safety floors, not tuning)
|
||||
/// - `feedback_no_atomicadd.md` (single-thread kernel)
|
||||
pub(crate) fn launch_hold_cost_scale_update(
|
||||
&self,
|
||||
) -> Result<(), MLError> {
|
||||
use crate::cuda_pipeline::sp14_isv_slots::{
|
||||
HOLD_COST_SCALE_INDEX, HOLD_COST_SCALE_MAX,
|
||||
HOLD_COST_SCALE_MIN, SENTINEL_HOLD_COST_SCALE, SENTINEL_HOLD_RATE_OBSERVED,
|
||||
HCS_TARGET_MEAN_INDEX, HCS_TARGET_M2_INDEX,
|
||||
HCS_DIFF_MEAN_INDEX, HCS_DIFF_M2_INDEX,
|
||||
HCS_PREV_TARGET_INDEX, HCS_SAMPLE_COUNT_INDEX,
|
||||
};
|
||||
use crate::cuda_pipeline::sp13_isv_slots::{
|
||||
HOLD_RATE_OBSERVED_EMA_INDEX, HOLD_RATE_TARGET_INDEX,
|
||||
};
|
||||
|
||||
debug_assert!(
|
||||
self.isv_signals_dev_ptr != 0,
|
||||
"launch_hold_cost_scale_update: isv_signals_dev_ptr must be allocated"
|
||||
);
|
||||
|
||||
// SP16 T3 (2026-05-08): hardcoded `α=0.05` removed — α is now
|
||||
// Wiener-optimal, derived from Welford accumulators in slots
|
||||
// [462..468). Per `pearl_wiener_optimal_adaptive_alpha`.
|
||||
self.hold_cost_scale_update_ops.launch(
|
||||
&self.stream,
|
||||
self.isv_signals_dev_ptr,
|
||||
HOLD_COST_SCALE_INDEX as i32,
|
||||
HOLD_RATE_OBSERVED_EMA_INDEX as i32,
|
||||
HOLD_RATE_TARGET_INDEX as i32,
|
||||
HCS_TARGET_MEAN_INDEX as i32,
|
||||
HCS_TARGET_M2_INDEX as i32,
|
||||
HCS_DIFF_MEAN_INDEX as i32,
|
||||
HCS_DIFF_M2_INDEX as i32,
|
||||
HCS_PREV_TARGET_INDEX as i32,
|
||||
HCS_SAMPLE_COUNT_INDEX as i32,
|
||||
SENTINEL_HOLD_COST_SCALE,
|
||||
SENTINEL_HOLD_RATE_OBSERVED,
|
||||
HOLD_COST_SCALE_MIN,
|
||||
HOLD_COST_SCALE_MAX,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// launch_hold_cost_scale_update DELETED by SP18 Phase 1 (2026-05-09).
|
||||
// The SP16 P2/T3 reactive Hold-cost-scale chain is replaced by the
|
||||
// SP18 D-leg structural Hold opportunity-cost reward (Phase 2).
|
||||
|
||||
/// SP8 (Fix 36, 2026-05-03): launch GPU-only `train_active_frac` canary
|
||||
/// producer.
|
||||
@@ -24424,14 +24313,8 @@ impl GpuDqnTrainer {
|
||||
let min_hold_temperature_update_ops =
|
||||
super::gpu_aux_trunk::MinHoldTemperatureUpdateOps::new(&stream)?;
|
||||
|
||||
// SP16 Phase 2 (2026-05-08): adaptive Hold cost scale producer.
|
||||
// Pre-loads the `CudaFunction` handle at construction per
|
||||
// `pearl_no_host_branches_in_captured_graph.md`. Per-epoch
|
||||
// boundary launch (same cadence and input chain as SP16-P1
|
||||
// MIN_HOLD_TEMPERATURE — they share slots 382 + 381 as input
|
||||
// and write to slots 460 + 461 respectively).
|
||||
let hold_cost_scale_update_ops =
|
||||
super::gpu_aux_trunk::HoldCostScaleUpdateOps::new(&stream)?;
|
||||
// hold_cost_scale_update_ops constructor DELETED by SP18 Phase 1
|
||||
// (2026-05-09).
|
||||
|
||||
// ── Speculative inference cache ──
|
||||
let speculative_h_s2 = stream.alloc_zeros::<f32>(b * sh2)
|
||||
@@ -25292,8 +25175,7 @@ impl GpuDqnTrainer {
|
||||
dd_saturation_floor_update_ops,
|
||||
// Class A audit-fix Batch 4-B (2026-05-08, Item 4): adaptive MIN_HOLD_TEMPERATURE producer.
|
||||
min_hold_temperature_update_ops,
|
||||
// SP16 Phase 2 (2026-05-08): adaptive Hold cost scale producer.
|
||||
hold_cost_scale_update_ops,
|
||||
// hold_cost_scale_update_ops field-init DELETED by SP18 Phase 1.
|
||||
speculative_h_s2,
|
||||
speculative_features,
|
||||
speculative_valid: false,
|
||||
|
||||
Reference in New Issue
Block a user