chore(ml-alpha): remove V1-forward test files (broken since X8 reshape)

Both tests exercised CfcTrunk::capture_graph_a + perception_forward_captured
+ snapshot_hidden, which feed V1-shaped CfC weights. After X8 the trunk's
CfC was reshaped to v2 layout (cfc_n_in=HIDDEN_DIM); the V1 forward path
now feeds FEATURE_DIM input into HIDDEN_DIM-shaped CfC — runtime garbage.

The methods themselves are still in trunk.rs (marked dead-code by rustc).
A deeper cleanup pass — deleting the V1 weight fields (heads_w_d, proj_*),
V1 per-step scratches, V1 cubin function handles, and the V1 forward
methods themselves — is a follow-up commit when fresh.

Verification: ml-alpha + ml-backtesting + fxt-backtest all build clean.
This commit is contained in:
jgrusewski
2026-05-19 09:08:04 +02:00
parent 395e0d3000
commit 71b467be40
2 changed files with 0 additions and 198 deletions

View File

@@ -1,91 +0,0 @@
//! CUDA Graph A capture + replay.
//!
//! Validates that the captured graph produces identical output to the
//! sequential dispatch path for the SAME input (scalars are frozen at
//! capture time per cudarc 0.19 semantics — see the trunk struct doc).
use approx::assert_relative_eq;
use ml_alpha::cfc::snap_features::Mbp10RawInput;
use ml_alpha::cfc::{CfcConfig, CfcTrunk};
use ml_alpha::heads::{N_HORIZONS, PROJ_DIM};
use ml_core::device::MlDevice;
fn test_device() -> MlDevice {
MlDevice::cuda(0).expect("CUDA 0 required for ml-alpha tests")
}
fn synthetic_input(dt_ns: u64) -> Mbp10RawInput {
let mut bid_px = [0.0f32; 10];
let mut bid_sz = [0.0f32; 10];
let mut ask_px = [0.0f32; 10];
let mut ask_sz = [0.0f32; 10];
for i in 0..10 {
bid_px[i] = 5500.00 - 0.25 * i as f32;
ask_px[i] = 5500.25 + 0.25 * i as f32;
bid_sz[i] = 12.0 + i as f32;
ask_sz[i] = 10.0 + i as f32 * 1.5;
}
Mbp10RawInput {
bid_px, bid_sz, ask_px, ask_sz,
prev_mid: 5499.875,
trade_signed_vol: 4.0,
trade_count: 7,
ts_ns: dt_ns,
prev_ts_ns: 0,
regime: [0.0; 6],
}
}
#[test]
fn graph_a_replay_matches_sequential() {
let dev = test_device();
let input = synthetic_input(20_000_000);
// Trunk A: sequential dispatch.
let mut trunk_seq = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0xCAFE).expect("seq init");
let (probs_seq, proj_seq) = trunk_seq.forward_snapshot(&input).expect("seq forward");
// Trunk B: same seed, capture + replay.
let mut trunk_g = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0xCAFE).expect("graph init");
trunk_g.capture_graph_a(&input).expect("capture");
let (probs_g, proj_g) = trunk_g.perception_forward_captured().expect("replay");
for k in 0..N_HORIZONS {
assert_relative_eq!(probs_seq[k], probs_g[k], epsilon = 1e-5, max_relative = 1e-5);
}
for j in 0..PROJ_DIM {
assert_relative_eq!(proj_seq[j], proj_g[j], epsilon = 1e-4, max_relative = 1e-4);
}
}
#[test]
fn graph_a_replay_is_deterministic() {
let dev = test_device();
let input = synthetic_input(15_000_000);
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0x5EED).expect("init");
trunk.capture_graph_a(&input).expect("capture");
let (p1, _) = trunk.perception_forward_captured().expect("replay 1");
let (p2, _) = trunk.perception_forward_captured().expect("replay 2");
let (p3, _) = trunk.perception_forward_captured().expect("replay 3");
for k in 0..N_HORIZONS {
assert_eq!(p1[k], p2[k], "replay {k} differs between calls 1 and 2");
assert_eq!(p2[k], p3[k], "replay {k} differs between calls 2 and 3");
}
}
#[test]
fn graph_a_replay_outputs_finite() {
let dev = test_device();
let input = synthetic_input(40_000_000);
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0xBEEF).expect("init");
trunk.capture_graph_a(&input).expect("capture");
let (probs, proj) = trunk.perception_forward_captured().expect("replay");
for &p in &probs {
assert!(p.is_finite() && (0.0..=1.0).contains(&p));
}
for &v in &proj {
assert!(v.is_finite());
}
}

View File

@@ -1,107 +0,0 @@
//! CfcTrunk forward — invariants on the sequentially-dispatched perception path.
use approx::assert_relative_eq;
use ml_alpha::cfc::snap_features::Mbp10RawInput;
use ml_alpha::cfc::{CfcConfig, CfcTrunk};
use ml_alpha::heads::{N_HORIZONS, PROJ_DIM};
use ml_core::device::MlDevice;
fn test_device() -> MlDevice {
MlDevice::cuda(0).expect("CUDA 0 required for ml-alpha tests")
}
fn synthetic_input(dt_ns: u64) -> Mbp10RawInput {
let mut bid_px = [0.0f32; 10];
let mut bid_sz = [0.0f32; 10];
let mut ask_px = [0.0f32; 10];
let mut ask_sz = [0.0f32; 10];
for i in 0..10 {
bid_px[i] = 5500.00 - 0.25 * i as f32;
ask_px[i] = 5500.25 + 0.25 * i as f32;
bid_sz[i] = 12.0 + i as f32;
ask_sz[i] = 10.0 + i as f32 * 1.5;
}
Mbp10RawInput {
bid_px,
bid_sz,
ask_px,
ask_sz,
prev_mid: 5499.875,
trade_signed_vol: 4.0,
trade_count: 7,
ts_ns: dt_ns,
prev_ts_ns: 0,
regime: [0.0; 6],
}
}
#[test]
fn forward_returns_probs_in_unit_interval() {
let dev = test_device();
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0xABCD).expect("init");
let (probs, proj) = trunk.forward_snapshot(&synthetic_input(1_000_000)).expect("forward");
assert_eq!(probs.len(), N_HORIZONS);
assert_eq!(proj.len(), PROJ_DIM);
for &p in &probs {
assert!((0.0..=1.0).contains(&p), "head prob {p} out of [0,1]");
}
}
#[test]
fn forward_updates_hidden_state() {
let dev = test_device();
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0xCAFE).expect("init");
let h0 = trunk.snapshot_hidden().expect("h0");
trunk
.forward_snapshot(&synthetic_input(20_000_000))
.expect("forward");
let h1 = trunk.snapshot_hidden().expect("h1");
let diff: f32 = h0.iter().zip(&h1).map(|(a, b)| (a - b).abs()).sum();
assert!(
diff > 1e-6,
"hidden state must change after a forward step (got total |Δh| = {diff})"
);
}
#[test]
fn forward_outputs_are_finite() {
let dev = test_device();
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0x1234).expect("init");
let (probs, proj) = trunk.forward_snapshot(&synthetic_input(50_000_000)).expect("forward");
for &p in &probs {
assert!(p.is_finite(), "prob {p} not finite");
}
for &v in &proj {
assert!(v.is_finite(), "proj {v} not finite");
}
}
#[test]
fn forward_layer_norm_proj_has_near_zero_mean() {
let dev = test_device();
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0x5EED).expect("init");
let (_, proj) = trunk.forward_snapshot(&synthetic_input(20_000_000)).expect("forward");
let mean: f32 = proj.iter().sum::<f32>() / PROJ_DIM as f32;
assert_relative_eq!(mean, 0.0, epsilon = 1e-3);
}
#[test]
fn forward_multi_step_advances_state_consistently() {
// After many forward steps, the hidden state should still be finite and
// within the bounded range expected by the CfC formula (tanh of pre).
let dev = test_device();
let mut trunk = CfcTrunk::new_random(&dev, &CfcConfig::default(), 0xBEEF).expect("init");
let mut last_ts = 0u64;
for k in 0..50 {
last_ts += 20_000_000;
let mut input = synthetic_input(last_ts);
input.prev_ts_ns = last_ts - 20_000_000;
// Slowly mutate trade_signed_vol so the input changes each step.
input.trade_signed_vol = k as f32 * 0.1;
trunk.forward_snapshot(&input).expect("forward");
}
let h = trunk.snapshot_hidden().expect("snapshot");
for (i, v) in h.iter().enumerate() {
assert!(v.is_finite(), "hidden[{i}] = {v} not finite after 50 steps");
}
}