use super::*;
#[test]
fn cuda_reaching_resident_sequence_window_uses_final_convergence_readback_only() {
let backend = CudaBackendRegistration::new(live_dispatcher());
let edge_offsets = vec![0u32, 1, 2, 3, 4, 4];
let edge_targets = vec![1u32, 2, 3, 4];
let edge_kind_mask = vec![edge_kind::CONTROL; 4];
let seed_bits = vec![0b00001u32];
let cpu = reaching_closure_cpu(5, &edge_offsets, &edge_targets, &edge_kind_mask, &seed_bits);
let plan = prepare_reaching_plan(5, &edge_offsets, &edge_targets, &edge_kind_mask)
.expect("reaching plan must prepare for sequence-window resident CUDA parity");
let config = DispatchConfig::default();
let pipeline = backend
.compile_native(plan.program(), &config)
.expect("CUDA native compile must succeed for resident reaching sequence-window parity")
.expect("CUDA backend registration must return a native compiled pipeline for resident reaching sequence-window parity");
let resident_plan = FixedPointResidentPlan::new(&backend, plan.graph(), pipeline)
.expect("CUDA backend must upload reaching sequence-window resident plan resources");
let mut scratch = weir::fixed_point_scratch::FixedPointScratch::default();
let mut resident_frontier = FixedPointResidentFrontierScratch::default();
backend.reset_telemetry();
let gpu = resident_plan
.reaching_reusing_frontier_sequence_window(
&backend,
&plan,
&seed_bits,
16,
&mut scratch,
&mut resident_frontier,
)
.expect("sequence-window resident CUDA reaching dispatch must converge");
let telemetry = backend.telemetry_snapshot();
assert_eq!(gpu, cpu);
assert_eq!(gpu, vec![0b11111u32]);
assert_eq!(
telemetry.readback_bytes, 8,
"Fix: sequence-window reaching resident solve must read only final frontier plus one changed flag, not poll every iteration."
);
assert!(
telemetry.sync_points < 16,
"Fix: sequence-window reaching resident solve must not synchronize once per fixed-point iteration; observed {} sync points.",
telemetry.sync_points
);
assert!(
telemetry.param_upload_bytes < telemetry.kernel_launches.saturating_mul(4),
"Fix: sequence-window reaching resident solve must hoist repeated fixed-point launch parameter uploads; observed {} parameter bytes across {} launches.",
telemetry.param_upload_bytes,
telemetry.kernel_launches
);
resident_plan
.free_with_frontier(&backend, &mut resident_frontier)
.expect("sequence-window resident reaching plan and frontier resources must free cleanly");
}
#[test]
fn cuda_reaching_resident_sequence_window_reads_changed_flag_not_previous_frontier() {
let backend = CudaBackendRegistration::new(live_dispatcher());
let node_count = 65_u32;
let edge_offsets = (0..=node_count)
.map(|node| node.min(node_count - 1))
.collect::<Vec<_>>();
let edge_targets = (1..node_count).collect::<Vec<_>>();
let edge_kind_mask = vec![edge_kind::CONTROL; edge_targets.len()];
let seed_bits = vec![1u32, 0, 0];
let cpu = reaching_closure_cpu(
node_count,
&edge_offsets,
&edge_targets,
&edge_kind_mask,
&seed_bits,
);
let plan = prepare_reaching_plan(node_count, &edge_offsets, &edge_targets, &edge_kind_mask)
.expect("multiword reaching plan must prepare for resident CUDA changed-flag parity");
let config = DispatchConfig::default();
let pipeline = backend
.compile_native(plan.program(), &config)
.expect("CUDA native compile must succeed for multiword resident reaching sequence-window parity")
.expect("CUDA backend registration must return a native compiled pipeline for multiword resident reaching sequence-window parity");
let resident_plan = FixedPointResidentPlan::new(&backend, plan.graph(), pipeline).expect(
"CUDA backend must upload multiword reaching sequence-window resident plan resources",
);
let mut scratch = weir::fixed_point_scratch::FixedPointScratch::default();
let mut resident_frontier = FixedPointResidentFrontierScratch::default();
backend.reset_telemetry();
let gpu = resident_plan
.reaching_reusing_frontier_sequence_window(
&backend,
&plan,
&seed_bits,
128,
&mut scratch,
&mut resident_frontier,
)
.expect("multiword changed-flag resident CUDA reaching dispatch must converge");
let telemetry = backend.telemetry_snapshot();
assert_eq!(gpu, cpu);
assert_eq!(gpu, vec![u32::MAX, u32::MAX, 1]);
assert_eq!(
telemetry.readback_bytes, 16,
"Fix: multiword changed-flag sequence window must read one 4-byte changed flag plus the 12-byte final frontier; reading a previous frontier would be 24 bytes."
);
assert!(
telemetry.sync_points <= 2,
"Fix: changed-flag sequence window must use one seed-upload fence and one resident-window fence, not per-iteration synchronization; observed {} sync points.",
telemetry.sync_points
);
resident_plan
.free_with_frontier(&backend, &mut resident_frontier)
.expect("multiword sequence-window resident reaching resources must free cleanly");
}