use super::*;
#[test]
fn fixed_point_resident_batch_reaching_into_reuses_result_buffer() {
let backend = FakeResidentBackend::new();
let graph = graph_fixture();
let pipeline = Arc::new(FakeResidentPipeline::new());
let mut batch = FixedPointResidentBatch::new();
let mut result = Vec::with_capacity(1);
let result_ptr = result.as_ptr();
let result_capacity = result.capacity();
batch
.reaching_into(
&backend,
pipeline.clone(),
&graph,
&[0b01],
1,
&DispatchConfig::default(),
&mut result,
)
.expect("first resident batch solve must fill caller-owned result");
assert_eq!(result, vec![0b01]);
assert_eq!(result.as_ptr(), result_ptr);
assert_eq!(result.capacity(), result_capacity);
result.clear();
batch
.reaching_into(
&backend,
pipeline,
&graph,
&[0b01],
1,
&DispatchConfig::default(),
&mut result,
)
.expect("second resident batch solve must reuse caller-owned result");
assert_eq!(result, vec![0b01]);
assert_eq!(result.as_ptr(), result_ptr);
assert_eq!(result.capacity(), result_capacity);
assert_eq!(batch.stats().frontier_allocations, 1);
assert_eq!(batch.stats().frontier_reuses, 1);
assert_eq!(batch.graph_cache_stats().hits, 1);
assert_eq!(batch.stats().resident_graph_cold_uploads, 1);
assert_eq!(batch.stats().resident_graph_warm_reuses, 1);
assert_eq!(
batch.stats().resident_graph_avoided_upload_bytes,
batch.stats().resident_graph_upload_bytes,
"second solve over the same resident graph must feed warm-residency avoided-upload accounting"
);
assert_eq!(
batch.stats().resident_graph_reuse_telemetry(),
vyre::ResidentGraphReuseTelemetry::from_counters(
1,
1,
batch.stats().resident_graph_upload_bytes,
batch.stats().resident_graph_avoided_upload_bytes
),
"resident batch graph reuse telemetry must use the backend-neutral Vyre vocabulary"
);
assert_eq!(batch.execution_plan_cache_stats().misses, 1);
assert_eq!(batch.execution_plan_cache_stats().hits, 1);
}
#[test]
fn fixed_point_resident_batch_live_points_to_and_slice_into_reuse_result_buffer() {
let backend = FakeResidentBackend::new();
let live_graph = graph_fixture_for_kind(crate::fixed_point_graph::FixedPointAnalysisKind::Live);
let points_to_graph =
graph_fixture_for_kind(crate::fixed_point_graph::FixedPointAnalysisKind::PointsToSubset);
let slice_graph =
graph_fixture_for_kind(crate::fixed_point_graph::FixedPointAnalysisKind::Slice);
let pipeline = Arc::new(FakeResidentPipeline::new());
let mut batch = FixedPointResidentBatch::new();
let mut result = Vec::with_capacity(1);
let result_ptr = result.as_ptr();
let result_capacity = result.capacity();
batch
.live_into(
&backend,
pipeline.clone(),
&live_graph,
&[0b01],
1,
&DispatchConfig::default(),
&mut result,
)
.expect("live resident batch solve must fill caller-owned result");
assert_eq!(result, vec![0b01]);
assert_eq!(result.as_ptr(), result_ptr);
assert_eq!(result.capacity(), result_capacity);
result.clear();
batch
.points_to_subset_into(
&backend,
pipeline.clone(),
&points_to_graph,
&[0b01],
1,
&DispatchConfig::default(),
&mut result,
)
.expect("points-to resident batch solve must reuse caller-owned result");
assert_eq!(result, vec![0b01]);
assert_eq!(result.as_ptr(), result_ptr);
assert_eq!(result.capacity(), result_capacity);
result.clear();
batch
.slice_into(
&backend,
pipeline,
&slice_graph,
&[0b01],
1,
&DispatchConfig::default(),
&mut result,
)
.expect("slice resident batch solve must reuse caller-owned result");
assert_eq!(result, vec![0b01]);
assert_eq!(result.as_ptr(), result_ptr);
assert_eq!(result.capacity(), result_capacity);
assert_eq!(batch.stats().frontier_allocations, 1);
assert_eq!(batch.stats().frontier_reuses, 2);
assert_eq!(
batch.graph_cache_stats().hits,
0,
"Fix: resident graph cache must not reuse one analysis family's graph handles for another family."
);
assert_eq!(batch.execution_plan_cache_stats().misses, 3);
assert_eq!(batch.execution_plan_cache_stats().hits, 0);
assert_eq!(
backend.uploads.lock().unwrap().len(),
18,
"live plus points-to plus slice resident batch solves must upload four graph buffers per analysis family plus frontier_in and frontier_out seed buffers per solve"
);
}