use super::*;
#[test]
fn fixed_point_batch_reuses_scratch_between_analyses() {
let second_analysis_saw_existing_output_slot = std::cell::Cell::new(false);
let phase = std::cell::Cell::new(0_u32);
let dispatch = |_: &vyre::ir::Program,
inputs: &[&[u8]],
_: Option<[u32; 3]>,
outputs: &mut Vec<Vec<u8>>| {
if inputs.len() < 6 {
return crate::fixed_point_closure::fallback_bitset_equal_dispatch(inputs, outputs);
}
if phase.get() == 1 && outputs.len() == 1 {
second_analysis_saw_existing_output_slot.set(true);
}
let frontier = u32::from_le_bytes(inputs[5][..4].try_into().unwrap());
let next = frontier | 0b11;
if outputs.is_empty() {
outputs.push(Vec::new());
}
outputs[0].clear();
outputs[0].extend_from_slice(&next.to_le_bytes());
Ok(())
};
let graph = CsrGraph::new(
2,
&[0, 1, 1],
&[1],
&[vyre_primitives::predicate::edge_kind::CONTROL],
);
let mut batch = FixedPointBatch::new(&dispatch);
let mut reaching_into = Vec::with_capacity(1);
let reaching_into_ptr = reaching_into.as_ptr();
let reaching = batch
.reaching(graph, &[0b01], 4)
.expect("batch reaching must converge");
batch
.reaching_into(graph, &[0b01], 4, &mut reaching_into)
.expect("batch reaching_into must converge into caller storage");
assert_eq!(reaching, vec![0b11]);
assert_eq!(reaching_into, vec![0b11]);
assert_eq!(
reaching_into.as_ptr(),
reaching_into_ptr,
"reaching_into must reuse caller result allocation"
);
assert_eq!(batch.scratch().output_slot_count(), 1);
phase.set(1);
let mut live_into = Vec::with_capacity(1);
let live_into_ptr = live_into.as_ptr();
let live = batch
.live(graph, &[0b10], 4)
.expect("batch live must converge");
batch
.live_into(graph, &[0b10], 4, &mut live_into)
.expect("batch live_into must converge into caller storage");
assert_eq!(live, vec![0b11]);
assert_eq!(live_into, vec![0b11]);
assert_eq!(
live_into.as_ptr(),
live_into_ptr,
"live_into must reuse caller result allocation"
);
let prepared = batch
.prepare_reaching(graph)
.expect("prepared graph should support execution planning");
let plan = batch
.execution_plan_for_prepared_graph(&prepared)
.expect("fixed-point batch execution plan must fit host byte accounting");
assert_eq!(plan.node_count, 2);
assert_eq!(
plan.execution_mode,
crate::fixed_point_scratch::FrontierExecutionMode::Dense
);
assert!(second_analysis_saw_existing_output_slot.get());
}