feat(crt-train): launch output_smoothness kernel after BCE in step_batched

This commit is contained in:
jgrusewski
2026-05-20 23:45:51 +02:00
parent 4a32186a5f
commit c9aa0c2a98

View File

@@ -1975,6 +1975,38 @@ impl PerceptionTrainer {
unsafe { launch.launch(bce_cfg).context("bce launch")?; }
}
// ── 5c. CRT.train output-smoothness regularizer ──
// λ[h]-weighted Σ (p[k]-p[k-1])² across adjacent positions
// in each sequence. Accumulates the analytic gradient INTO
// `self.grad_probs_per_k_d` (which BCE just overwrote);
// the heads_bwd K-loop below consumes the sum.
//
// Per `pearl_no_host_branches_in_captured_graph`: kernel
// launch only — all scalars (k_i, b_i) and buffer pointers
// are fixed across captures (seq_len and batch_size are
// config-immutable). λ is uploaded once at construction;
// when `cfg.smoothness_base_lambda == 0.0` the kernel
// produces zero loss + zero grad, behaviorally identical
// to the pre-intervention path.
let k_seq_i = k_seq as i32;
let b_sz_i = b_sz as i32;
let smooth_cfg = LaunchConfig {
grid_dim: (1, 1, 1),
block_dim: (256, 1, 1),
shared_mem_bytes: 0,
};
{
let mut launch = self.stream.launch_builder(&self.smoothness_fn);
launch
.arg(&self.probs_per_k_d)
.arg(&self.smoothness_lambda_d)
.arg(&k_seq_i).arg(&b_sz_i)
.arg(&mut self.smoothness_loss_d)
.arg(&mut self.smoothness_loss_per_horizon_d)
.arg(&mut self.grad_probs_per_k_d);
unsafe { launch.launch(smooth_cfg).context("output_smoothness launch")?; }
}
// ── 5a. (v2 reserved) — per-horizon Q_h backward removed at V1.
// v2 backward path will live here in commit V10.
@@ -2523,6 +2555,27 @@ impl PerceptionTrainer {
self.loss_host_d.dev_ptr, src_ptr, 4, self.stream.cu_stream(),
).context("loss dtod → mapped-pinned")?;
}
// CRT.train: shadow smoothness telemetry buffers to mapped-pinned
// host slots for zero-sync operator reads. Same stream, same
// capture region — adjacent to the loss_d shadow above.
unsafe {
let (smooth_loss_src_ptr, _g) = self.smoothness_loss_d.device_ptr(&self.stream);
cudarc::driver::result::memcpy_dtod_async(
self.smoothness_loss_host_d.dev_ptr,
smooth_loss_src_ptr,
std::mem::size_of::<f32>(),
self.stream.cu_stream(),
).context("smoothness_loss_host_d shadow")?;
}
unsafe {
let (smooth_loss_ph_src_ptr, _g) = self.smoothness_loss_per_horizon_d.device_ptr(&self.stream);
cudarc::driver::result::memcpy_dtod_async(
self.smoothness_loss_per_horizon_host_d.dev_ptr,
smooth_loss_ph_src_ptr,
N_HORIZONS * std::mem::size_of::<f32>(),
self.stream.cu_stream(),
).context("smoothness_loss_per_horizon_host_d shadow")?;
}
Ok(())
}