//! P1 regression test: per-backtest sim parameter arrays. With uniform //! config across N backtests, all N must produce the same market_target //! decision (proves the per-backtest indexing reduces correctly to the //! pre-refactor scalar-broadcast semantics). //! //! Pair: the independence test (proving DIFFERENT per-backtest configs //! produce different outputs) lands alongside the P2 inflight-limits //! kernel where the read_first_inflight_arrival_ts helper exists. use anyhow::Result; use ml_backtesting::sim::{BatchedSimConfig, LobSimCuda, UniformSimParams}; use ml_core::device::MlDevice; #[test] #[ignore = "requires CUDA"] fn parallel_sim_equivalence_with_uniform_config() -> Result<()> { let dev = match MlDevice::cuda(0) { Ok(d) => d, Err(e) => { eprintln!("skipping: cuda device unavailable ({e})"); return Ok(()); } }; let mut sim = LobSimCuda::new(8, &dev)?; sim.broadcast_alpha(&[0.8, 0.8, 0.8, 0.8, 0.8])?; let cfg = BatchedSimConfig::from_uniform( 8, &UniformSimParams { target_annual_vol_units: 50.0, annualisation_factor: 825.0, max_lots: 5, latency_ns: 0, kelly_frac_floor: 0.20, sharpe_weight_floor: 0.10, threshold: 0.0, cost_per_lot_per_side: 0.0, }, ); sim.step_decision_with_latency(0, &cfg)?; let first = sim.read_market_target(0)?; for b in 1..8 { let got = sim.read_market_target(b)?; assert_eq!( got, first, "backtest {b} differs from backtest 0 under uniform config: {got:?} vs {first:?}" ); } // And the uniform-config result must equal the result we'd get from // a single-backtest sim (preserves pre-refactor behaviour). assert_eq!(first.0, 0, "uniform config with p_h=0.8 should produce a buy; got side={}", first.0); assert!(first.1 >= 1, "uniform-config size {} < 1", first.1); Ok(()) }