#![forbid(unsafe_code)]
use std::cell::RefCell;
use vyre_foundation::ir::{BufferAccess, Expr, MemoryKind, Node, Program};
use vyre_self_substrate::optimizer::dce_via_encoded::gpu_dce;
use vyre_self_substrate::optimizer::dispatcher::{DispatchError, OptimizerDispatcher};
fn declared_input_slots(program: &Program) -> usize {
program
.buffers()
.iter()
.filter(|buffer| {
if buffer.kind() == MemoryKind::Shared
|| buffer.kind() == MemoryKind::Persistent
|| buffer.access() == BufferAccess::Workgroup
{
return false;
}
if buffer.is_output || buffer.pipeline_live_out {
return false;
}
matches!(
buffer.access(),
BufferAccess::ReadOnly | BufferAccess::ReadWrite | BufferAccess::Uniform
)
})
.count()
}
#[derive(Default)]
struct RecordingDispatcher {
calls: RefCell<Vec<(usize, usize)>>,
grids: RefCell<Vec<Option<[u32; 3]>>>,
}
impl OptimizerDispatcher for RecordingDispatcher {
fn dispatch(
&self,
program: &Program,
inputs: &[Vec<u8>],
grid_override: Option<[u32; 3]>,
) -> Result<Vec<Vec<u8>>, DispatchError> {
self.calls
.borrow_mut()
.push((inputs.len(), declared_input_slots(program)));
self.grids.borrow_mut().push(grid_override);
let frontier_out = inputs
.get(6)
.cloned()
.ok_or_else(|| DispatchError::BackendError("missing frontier_out slot".to_string()))?;
Ok(vec![
frontier_out,
0u32.to_le_bytes().to_vec(),
1u32.to_le_bytes().to_vec(),
])
}
}
fn wrapped(entry: Vec<Node>) -> Program {
Program::wrapped(Vec::new(), [1, 1, 1], entry)
}
#[test]
fn gpu_dce_fills_every_input_slot_its_analysis_program_declares() {
let dispatcher = RecordingDispatcher::default();
gpu_dce(
wrapped(vec![
Node::let_bind("a", Expr::u32(7)),
Node::let_bind("b", Expr::u32(9)),
]),
&dispatcher,
)
.expect("Fix: gpu_dce must complete against a converged recording dispatcher");
let calls = dispatcher.calls.borrow();
assert!(
!calls.is_empty(),
"Fix: gpu_dce must dispatch its liveness analysis at least once."
);
for (index, (supplied, declared)) in calls.iter().enumerate() {
assert_eq!(
supplied, declared,
"Fix: gpu_dce dispatch {index} supplied {supplied} input slot(s) for an analysis \
program declaring {declared}. Update the slot filler in \
vyre-self-substrate/src/optimizer/dce_via_encoded.rs to match the program."
);
}
}
#[test]
fn the_dce_analysis_program_declares_nine_input_slots() {
let dispatcher = RecordingDispatcher::default();
gpu_dce(
wrapped(vec![Node::let_bind("a", Expr::u32(7))]),
&dispatcher,
)
.expect("Fix: gpu_dce must complete against a converged recording dispatcher");
let calls = dispatcher.calls.borrow();
let (supplied, declared) = calls
.first()
.copied()
.expect("Fix: gpu_dce must dispatch its liveness analysis at least once.");
assert_eq!(
declared, 9,
"Fix: the persistent-BFS DCE layout is six read-only graph buffers plus the ReadWrite \
frontier_out, changed and converged slots. A different count means the layout changed; \
update this pin and the slot filler together."
);
assert_eq!(supplied, 9);
}
#[test]
fn gpu_dce_pins_its_analysis_to_a_single_workgroup() {
let dispatcher = RecordingDispatcher::default();
gpu_dce(
wrapped(vec![
Node::let_bind("a", Expr::u32(7)),
Node::let_bind("b", Expr::u32(9)),
]),
&dispatcher,
)
.expect("Fix: gpu_dce must complete against a converged recording dispatcher");
let grids = dispatcher.grids.borrow();
assert!(
!grids.is_empty(),
"Fix: gpu_dce must dispatch its liveness analysis at least once."
);
for (index, grid) in grids.iter().enumerate() {
assert_eq!(
*grid,
Some([1, 1, 1]),
"Fix: gpu_dce dispatch {index} launched with grid {grid:?} instead of a single \
workgroup. The analysis kernel's early exit attributes each discovery to the one \
lane whose atomic_or flipped the bit, so splitting it across workgroups lets a \
duplicate group steal a discovery and strand the essential group at changed = 0. \
Pin it with Some([1, 1, 1]) in dce_via_encoded.rs."
);
}
}