use crate::ifds_csr_split::split_columns_into;
use crate::ifds_gpu::{
try_ifds_words, validate_ifds_problem, IfdsResidentDispatch, IfdsShape, ResidentPreparedIfdsCsr,
};
use crate::ifds_resident_direct_batch::graph_hash;
use crate::ifds_resident_direct_prepare_scratch::DirectResidentIfdsPrepareScratch;
use std::sync::Arc;
use vyre_foundation::ir::model::expr::Ident;
use vyre_foundation::ir::{BufferAccess, BufferDecl, DataType, Expr, Node, Program};
use vyre_primitives::graph::exploded::{build_ifds_csr_program, validate_ifds_csr_layout};
const DIRECT_CSR_INPUT_COUNT: usize = 13;
const DIRECT_PG_NODES_BUFFER: &str = "direct_pg_nodes";
const DIRECT_PG_EDGE_KIND_MASK_BUFFER: &str = "direct_pg_edge_kind_mask";
const DIRECT_PG_NODE_TAGS_BUFFER: &str = "direct_pg_node_tags";
const DIRECT_METADATA_FILL_OP: &str = "weir::ifds_gpu::direct_prepare_fill_metadata";
const DIRECT_LINEAR_TILE_X: u32 = 65_535;
#[allow(clippy::too_many_arguments)]
pub fn prepare_ifds_csr_resident_direct_via<D>(
dispatch: &D,
num_procs: u32,
blocks_per_proc: u32,
facts_per_proc: u32,
intra_edges: &[(u32, u32, u32)],
inter_edges: &[(u32, u32, u32, u32)],
flow_gen: &[(u32, u32, u32)],
flow_kill: &[(u32, u32, u32)],
) -> Result<ResidentPreparedIfdsCsr<D::Resource>, String>
where
D: IfdsResidentDispatch,
{
let mut scratch = DirectResidentIfdsPrepareScratch::default();
let mut resource_scratch = Vec::new();
prepare_ifds_csr_resident_direct_with_scratch_via(
dispatch,
num_procs,
blocks_per_proc,
facts_per_proc,
intra_edges,
inter_edges,
flow_gen,
flow_kill,
&mut scratch,
&mut resource_scratch,
)
}
#[allow(clippy::too_many_arguments)]
pub fn prepare_ifds_csr_resident_direct_with_scratch_via<D>(
dispatch: &D,
num_procs: u32,
blocks_per_proc: u32,
facts_per_proc: u32,
intra_edges: &[(u32, u32, u32)],
inter_edges: &[(u32, u32, u32, u32)],
flow_gen: &[(u32, u32, u32)],
flow_kill: &[(u32, u32, u32)],
scratch: &mut DirectResidentIfdsPrepareScratch,
resource_scratch: &mut Vec<D::Resource>,
) -> Result<ResidentPreparedIfdsCsr<D::Resource>, String>
where
D: IfdsResidentDispatch,
{
scratch.clear_for_prepare();
validate_ifds_problem(
"weir IFDS direct resident CSR prepare",
num_procs,
blocks_per_proc,
facts_per_proc,
intra_edges,
inter_edges,
flow_gen,
flow_kill,
&[],
)?;
let pre_edge_count = intra_edges
.len()
.checked_add(inter_edges.len())
.and_then(|count| count.checked_add(flow_gen.len()))
.and_then(|count| count.checked_add(flow_kill.len()))
.ok_or_else(|| {
"weir IFDS direct resident CSR prepare edge count overflows usize. Fix: shard the IFDS problem before dispatch.".to_string()
})?;
let pre_edge_count = u32::try_from(pre_edge_count).map_err(|error| {
format!(
"weir IFDS direct resident CSR prepare edge count does not fit u32: {error}. Fix: shard the IFDS problem or reduce the encoded domain before dispatch."
)
})?;
let pre_shape = IfdsShape {
num_procs,
blocks_per_proc,
facts_per_proc,
edge_count: pre_edge_count,
};
let intra_count = u32::try_from(intra_edges.len()).map_err(|error| {
format!(
"weir IFDS direct resident CSR prepare received too many intra edges for u32 indexing: {error}. Fix: shard the IFDS graph before dispatch."
)
})?;
let inter_count = u32::try_from(inter_edges.len()).map_err(|error| {
format!(
"weir IFDS direct resident CSR prepare received too many inter edges for u32 indexing: {error}. Fix: shard the IFDS graph before dispatch."
)
})?;
let gen_count = u32::try_from(flow_gen.len()).map_err(|error| {
format!(
"weir IFDS direct resident CSR prepare received too many GEN entries for u32 indexing: {error}. Fix: shard the IFDS graph before dispatch."
)
})?;
let kill_count = u32::try_from(flow_kill.len()).map_err(|error| {
format!(
"weir IFDS direct resident CSR prepare received too many KILL entries for u32 indexing: {error}. Fix: shard the IFDS graph before dispatch."
)
})?;
let layout = validate_ifds_csr_layout(
num_procs,
blocks_per_proc,
facts_per_proc,
intra_count,
inter_count,
gen_count,
)
.map_err(|error| format!("weir IFDS direct resident CSR prepare invalid layout: {error}"))?;
let total_nodes = layout.total_nodes;
let max_col_count = layout.max_col_count;
split_columns_into(
intra_edges,
&mut [
&mut scratch.intra_proc,
&mut scratch.intra_src_block,
&mut scratch.intra_dst_block,
],
&[
"IFDS direct prepare split triple first column",
"IFDS direct prepare split triple second column",
"IFDS direct prepare split triple third column",
],
)?;
split_columns_into(
inter_edges,
&mut [
&mut scratch.inter_src_proc,
&mut scratch.inter_src_block,
&mut scratch.inter_dst_proc,
&mut scratch.inter_dst_block,
],
&[
"IFDS direct prepare split quad first column",
"IFDS direct prepare split quad second column",
"IFDS direct prepare split quad third column",
"IFDS direct prepare split quad fourth column",
],
)?;
split_columns_into(
flow_gen,
&mut [
&mut scratch.gen_proc,
&mut scratch.gen_block,
&mut scratch.gen_fact,
],
&[
"IFDS direct prepare split triple first column",
"IFDS direct prepare split triple second column",
"IFDS direct prepare split triple third column",
],
)?;
split_columns_into(
flow_kill,
&mut [
&mut scratch.kill_proc,
&mut scratch.kill_block,
&mut scratch.kill_fact,
],
&[
"IFDS direct prepare split triple first column",
"IFDS direct prepare split triple second column",
"IFDS direct prepare split triple third column",
],
)?;
let total_nodes_usize = crate::dispatch_decode::u32_to_usize(
layout.total_nodes,
"weir direct resident IFDS total node count",
)?;
let max_col_count_usize = crate::dispatch_decode::u32_to_usize(
layout.max_col_count,
"weir direct resident IFDS maximum CSR column count",
)?;
let mut allocated =
crate::staging_reserve::reserved_vec(20, "IFDS direct resident rollback resource")?;
let prepared = (|| {
crate::staging_reserve::ensure_vec_slots_at_least(
&mut scratch.input_bytes,
DIRECT_CSR_INPUT_COUNT,
"IFDS direct resident input byte slot",
)?;
padded_pack_into(&scratch.intra_proc, &mut scratch.input_bytes[0])?;
padded_pack_into(&scratch.intra_src_block, &mut scratch.input_bytes[1])?;
padded_pack_into(&scratch.intra_dst_block, &mut scratch.input_bytes[2])?;
padded_pack_into(&scratch.inter_src_proc, &mut scratch.input_bytes[3])?;
padded_pack_into(&scratch.inter_src_block, &mut scratch.input_bytes[4])?;
padded_pack_into(&scratch.inter_dst_proc, &mut scratch.input_bytes[5])?;
padded_pack_into(&scratch.inter_dst_block, &mut scratch.input_bytes[6])?;
padded_pack_into(&scratch.gen_proc, &mut scratch.input_bytes[7])?;
padded_pack_into(&scratch.gen_block, &mut scratch.input_bytes[8])?;
padded_pack_into(&scratch.gen_fact, &mut scratch.input_bytes[9])?;
padded_pack_into(&scratch.kill_proc, &mut scratch.input_bytes[10])?;
padded_pack_into(&scratch.kill_block, &mut scratch.input_bytes[11])?;
padded_pack_into(&scratch.kill_fact, &mut scratch.input_bytes[12])?;
let mut input_resources: [Option<D::Resource>; DIRECT_CSR_INPUT_COUNT] =
std::array::from_fn(|_| None);
for (idx, bytes) in scratch
.input_bytes
.iter()
.take(DIRECT_CSR_INPUT_COUNT)
.enumerate()
{
input_resources[idx] =
Some(allocate_one(dispatch, "csr_input", bytes, &mut allocated)?);
}
let row_ptr_byte_len = total_nodes_usize
.checked_add(1)
.and_then(|words| words.checked_mul(std::mem::size_of::<u32>()))
.ok_or_else(|| {
"weir IFDS direct resident CSR row_ptr byte length overflows usize. Fix: shard the IFDS graph before dispatch.".to_string()
})?;
let row_cursor_byte_len = total_nodes_usize
.max(1)
.checked_mul(std::mem::size_of::<u32>())
.ok_or_else(|| {
"weir IFDS direct resident CSR row_cursor byte length overflows usize. Fix: shard the IFDS graph before dispatch.".to_string()
})?;
let col_idx_byte_len = max_col_count_usize
.max(1)
.checked_mul(std::mem::size_of::<u32>())
.ok_or_else(|| {
"weir IFDS direct resident CSR col_idx byte length overflows usize. Fix: shard the IFDS graph before dispatch.".to_string()
})?;
let col_len_byte_len = std::mem::size_of::<u32>();
let row_ptr = allocate_len(dispatch, "row_ptr", row_ptr_byte_len, &mut allocated)?;
let row_cursor = allocate_len(dispatch, "row_cursor", row_cursor_byte_len, &mut allocated)?;
let col_idx = allocate_len(dispatch, "col_idx", col_idx_byte_len, &mut allocated)?;
let col_len = allocate_len(dispatch, "col_len", col_len_byte_len, &mut allocated)?;
crate::staging_reserve::ensure_vec_slots_at_least(
&mut scratch.generated_zero_bytes,
4,
"IFDS direct resident generated CSR zero byte slot",
)?;
crate::dispatch_decode::try_write_zero_bytes(
&mut scratch.generated_zero_bytes[0],
row_ptr_byte_len,
"IFDS direct resident row_ptr zero staging",
)?;
crate::dispatch_decode::try_write_zero_bytes(
&mut scratch.generated_zero_bytes[1],
row_cursor_byte_len,
"IFDS direct resident row_cursor zero staging",
)?;
crate::dispatch_decode::try_write_zero_bytes(
&mut scratch.generated_zero_bytes[2],
col_idx_byte_len,
"IFDS direct resident col_idx zero staging",
)?;
crate::dispatch_decode::try_write_zero_bytes(
&mut scratch.generated_zero_bytes[3],
col_len_byte_len,
"IFDS direct resident col_len zero staging",
)?;
let uploads = [
(
require_input_resource(&input_resources, 0)?,
scratch.input_bytes[0].as_slice(),
),
(
require_input_resource(&input_resources, 1)?,
scratch.input_bytes[1].as_slice(),
),
(
require_input_resource(&input_resources, 2)?,
scratch.input_bytes[2].as_slice(),
),
(
require_input_resource(&input_resources, 3)?,
scratch.input_bytes[3].as_slice(),
),
(
require_input_resource(&input_resources, 4)?,
scratch.input_bytes[4].as_slice(),
),
(
require_input_resource(&input_resources, 5)?,
scratch.input_bytes[5].as_slice(),
),
(
require_input_resource(&input_resources, 6)?,
scratch.input_bytes[6].as_slice(),
),
(
require_input_resource(&input_resources, 7)?,
scratch.input_bytes[7].as_slice(),
),
(
require_input_resource(&input_resources, 8)?,
scratch.input_bytes[8].as_slice(),
),
(
require_input_resource(&input_resources, 9)?,
scratch.input_bytes[9].as_slice(),
),
(
require_input_resource(&input_resources, 10)?,
scratch.input_bytes[10].as_slice(),
),
(
require_input_resource(&input_resources, 11)?,
scratch.input_bytes[11].as_slice(),
),
(
require_input_resource(&input_resources, 12)?,
scratch.input_bytes[12].as_slice(),
),
(&row_ptr, scratch.generated_zero_bytes[0].as_slice()),
(&row_cursor, scratch.generated_zero_bytes[1].as_slice()),
(&col_idx, scratch.generated_zero_bytes[2].as_slice()),
(&col_len, scratch.generated_zero_bytes[3].as_slice()),
];
dispatch.upload_resident_many(&uploads).map_err(|error| {
format!("weir IFDS direct resident CSR input/generated upload failed: {error}")
})?;
resource_scratch.clear();
crate::staging_reserve::reserve_vec(
resource_scratch,
17,
"IFDS direct resident dispatch resource",
)?;
for idx in 0..DIRECT_CSR_INPUT_COUNT {
resource_scratch.push(require_input_resource(&input_resources, idx)?.clone());
}
resource_scratch.extend([
row_ptr.clone(),
row_cursor.clone(),
col_idx.clone(),
col_len.clone(),
]);
let prev_capacity = resource_scratch.capacity();
let resources: [D::Resource; 17] =
std::mem::replace(resource_scratch, Vec::with_capacity(prev_capacity))
.try_into()
.map_err(
|resources: Vec<D::Resource>| {
format!(
"weir IFDS direct resident CSR dispatch ABI assembled {} resources instead of 17. Fix: keep the fixed CSR input count and generated CSR resources in sync.",
resources.len()
)
},
)?;
let program = build_ifds_csr_program(
num_procs,
blocks_per_proc,
facts_per_proc,
intra_count,
inter_count,
gen_count,
kill_count,
max_col_count,
);
dispatch.dispatch_resident(&program, &resources, Some([1, 1, 1]))?;
let shape = IfdsShape {
edge_count: max_col_count,
..pre_shape
};
let words = try_ifds_words(total_nodes)?;
let pg_nodes = allocate_len(
dispatch,
"pg_nodes",
total_nodes_usize
.max(1)
.checked_mul(std::mem::size_of::<u32>())
.ok_or_else(|| {
"weir IFDS direct resident CSR pg_nodes byte length overflows usize. Fix: shard the IFDS graph before dispatch.".to_string()
})?,
&mut allocated,
)?;
let pg_edge_kind_mask =
allocate_len(
dispatch,
"pg_edge_kind_mask",
max_col_count_usize
.max(1)
.checked_mul(std::mem::size_of::<u32>())
.ok_or_else(|| {
"weir IFDS direct resident CSR edge-kind byte length overflows usize. Fix: shard the IFDS graph before dispatch.".to_string()
})?,
&mut allocated,
)?;
let pg_node_tags =
allocate_len(
dispatch,
"pg_node_tags",
total_nodes_usize
.max(1)
.checked_mul(std::mem::size_of::<u32>())
.ok_or_else(|| {
"weir IFDS direct resident CSR node-tag byte length overflows usize. Fix: shard the IFDS graph before dispatch.".to_string()
})?,
&mut allocated,
)?;
let fill_metadata =
direct_program_graph_metadata_program(total_nodes.max(1), max_col_count.max(1));
let fill_metadata_resources = [
pg_nodes.clone(),
pg_edge_kind_mask.clone(),
pg_node_tags.clone(),
];
dispatch.dispatch_resident(
&fill_metadata,
&fill_metadata_resources,
Some(direct_linear_grid(
total_nodes.max(1).max(max_col_count.max(1)),
)?),
)?;
for resource in input_resources.into_iter().flatten() {
dispatch.free_resident(resource)?;
}
dispatch.free_resident(row_cursor)?;
dispatch.free_resident(col_len)?;
allocated.clear();
Ok(ResidentPreparedIfdsCsr::from_parts(
shape,
total_nodes,
words,
graph_hash(intra_edges, inter_edges, flow_gen, flow_kill),
pg_nodes,
row_ptr,
col_idx,
pg_edge_kind_mask,
pg_node_tags,
))
})();
if prepared.is_err() {
for (label, resource) in allocated {
let _ = dispatch.free_resident(resource).map_err(|error| {
format!("weir IFDS direct resident CSR rollback free {label} failed: {error}")
});
}
}
prepared
}
fn padded_pack_into(words: &[u32], bytes: &mut Vec<u8>) -> Result<(), String> {
if words.is_empty() {
crate::dispatch_decode::try_write_zero_bytes(
bytes,
std::mem::size_of::<u32>(),
"IFDS direct resident zero byte staging",
)
} else {
crate::dispatch_decode::try_pack_u32_into(
words,
bytes,
"IFDS direct resident u32 byte staging",
)
}
}
fn allocate_one<D: IfdsResidentDispatch>(
dispatch: &D,
label: &'static str,
bytes: &[u8],
allocated: &mut Vec<(&'static str, D::Resource)>,
) -> Result<D::Resource, String> {
allocate_len(dispatch, label, bytes.len(), allocated)
}
fn allocate_len<D: IfdsResidentDispatch>(
dispatch: &D,
label: &'static str,
byte_len: usize,
allocated: &mut Vec<(&'static str, D::Resource)>,
) -> Result<D::Resource, String> {
let resource = dispatch.allocate_resident(byte_len).map_err(|error| {
format!("weir IFDS direct resident CSR allocate {label} failed: {error}")
})?;
allocated.push((label, resource.clone()));
Ok(resource)
}
fn direct_linear_grid(words: u32) -> Result<[u32; 3], String> {
let lanes = words.max(1);
let y_lanes = u64::from(lanes).div_ceil(u64::from(DIRECT_LINEAR_TILE_X));
if y_lanes > u64::from(DIRECT_LINEAR_TILE_X) {
return Err(format!(
"weir IFDS direct resident CSR initialization requires {lanes} lanes, exceeding the 2D single-dispatch backend limit. Fix: shard resident initialization into multiple dispatches."
));
}
Ok([
lanes.min(DIRECT_LINEAR_TILE_X),
u32::try_from(y_lanes).map_err(|error| {
format!(
"weir IFDS direct resident CSR initialization grid y dimension does not fit u32: {error}. Fix: shard resident initialization into multiple dispatches."
)
})?,
1,
])
}
fn direct_linear_index() -> Expr {
Expr::add(
Expr::mul(Expr::gid_y(), Expr::u32(DIRECT_LINEAR_TILE_X)),
Expr::gid_x(),
)
}
fn direct_program_graph_metadata_program(node_words: u32, edge_words: u32) -> Program {
let index = direct_linear_index();
Program::wrapped(
vec![
BufferDecl::storage(
DIRECT_PG_NODES_BUFFER,
0,
BufferAccess::ReadWrite,
DataType::U32,
)
.with_count(node_words.max(1)),
BufferDecl::storage(
DIRECT_PG_EDGE_KIND_MASK_BUFFER,
1,
BufferAccess::ReadWrite,
DataType::U32,
)
.with_count(edge_words.max(1)),
BufferDecl::storage(
DIRECT_PG_NODE_TAGS_BUFFER,
2,
BufferAccess::ReadWrite,
DataType::U32,
)
.with_count(node_words.max(1)),
],
[1, 1, 1],
vec![Node::Region {
generator: Ident::from(DIRECT_METADATA_FILL_OP),
source_region: None,
body: Arc::new(vec![
Node::if_then(
Expr::lt(index.clone(), Expr::u32(node_words)),
vec![Node::store(
DIRECT_PG_NODES_BUFFER,
index.clone(),
Expr::u32(0),
)],
),
Node::if_then(
Expr::lt(index.clone(), Expr::u32(edge_words)),
vec![Node::store(
DIRECT_PG_EDGE_KIND_MASK_BUFFER,
index.clone(),
Expr::u32(1),
)],
),
Node::if_then(
Expr::lt(index.clone(), Expr::u32(node_words)),
vec![Node::store(DIRECT_PG_NODE_TAGS_BUFFER, index, Expr::u32(0))],
),
]),
}],
)
}
fn require_input_resource<R>(
input_resources: &[Option<R>; DIRECT_CSR_INPUT_COUNT],
index: usize,
) -> Result<&R, String> {
input_resources
.get(index)
.and_then(Option::as_ref)
.ok_or_else(|| {
format!(
"weir IFDS direct resident CSR input resource {index} missing before dispatch. Fix: allocate every fixed CSR input resource before upload."
)
})
}
#[cfg(test)]
mod tests {
use super::*;
use std::cell::RefCell;
#[derive(Default)]
struct PrepareDispatch {
buffers: RefCell<Vec<Vec<u8>>>,
upload_batch_lens: RefCell<Vec<usize>>,
dispatch_resource_lens: RefCell<Vec<usize>>,
freed: RefCell<Vec<usize>>,
}
impl IfdsResidentDispatch for PrepareDispatch {
type Resource = usize;
fn resident_backend_id(&self) -> &'static str {
"weir_test_direct_prepare_upload_batch"
}
fn allocate_resident(&self, byte_len: usize) -> Result<Self::Resource, String> {
let mut buffers = self.buffers.borrow_mut();
let resource = buffers.len();
buffers.push(vec![0; byte_len]);
Ok(resource)
}
fn upload_resident(&self, resource: &Self::Resource, bytes: &[u8]) -> Result<(), String> {
self.buffers.borrow_mut()[*resource] = bytes.to_vec();
Ok(())
}
fn upload_resident_many(&self, uploads: &[(&Self::Resource, &[u8])]) -> Result<(), String> {
self.upload_batch_lens.borrow_mut().push(uploads.len());
for &(resource, bytes) in uploads {
self.upload_resident(resource, bytes)?;
}
Ok(())
}
fn download_resident(&self, resource: &Self::Resource) -> Result<Vec<u8>, String> {
Ok(self.buffers.borrow()[*resource].clone())
}
fn download_resident_into(
&self,
resource: &Self::Resource,
output: &mut Vec<u8>,
) -> Result<(), String> {
output.clear();
output.extend_from_slice(&self.buffers.borrow()[*resource]);
Ok(())
}
fn download_resident_range(
&self,
resource: &Self::Resource,
byte_offset: usize,
byte_len: usize,
) -> Result<Vec<u8>, String> {
let buffer = self.buffers.borrow();
let end = byte_offset
.checked_add(byte_len)
.ok_or_else(|| "fake direct prepare range overflow".to_string())?;
Ok(buffer[*resource][byte_offset..end].to_vec())
}
fn download_resident_range_into(
&self,
resource: &Self::Resource,
byte_offset: usize,
byte_len: usize,
output: &mut Vec<u8>,
) -> Result<(), String> {
output.clear();
output.extend_from_slice(&self.download_resident_range(
resource,
byte_offset,
byte_len,
)?);
Ok(())
}
fn free_resident(&self, resource: Self::Resource) -> Result<(), String> {
self.freed.borrow_mut().push(resource);
Ok(())
}
fn dispatch_resident(
&self,
_program: &Program,
resources: &[Self::Resource],
_grid_override: Option<[u32; 3]>,
) -> Result<(), String> {
self.dispatch_resource_lens
.borrow_mut()
.push(resources.len());
Ok(())
}
}
#[test]
fn direct_prepare_reuses_resource_scratch_across_calls() {
let dispatch = PrepareDispatch::default();
let mut scratch = DirectResidentIfdsPrepareScratch::default();
let mut resource_scratch = Vec::new();
let _ = prepare_ifds_csr_resident_direct_with_scratch_via(
&dispatch,
1,
1,
1,
&[(0, 0, 0)],
&[],
&[],
&[],
&mut scratch,
&mut resource_scratch,
)
.expect("first direct prepare must succeed");
let cap_after_first = resource_scratch.capacity();
let _ = prepare_ifds_csr_resident_direct_with_scratch_via(
&dispatch,
1,
1,
1,
&[(0, 0, 0)],
&[],
&[],
&[],
&mut scratch,
&mut resource_scratch,
)
.expect("second direct prepare must succeed");
assert_eq!(
resource_scratch.capacity(),
cap_after_first,
"direct resident prepare must reuse resource scratch capacity across calls"
);
}
#[test]
fn direct_prepare_batches_input_and_generated_zero_uploads_once() {
let dispatch = PrepareDispatch::default();
let prepared =
prepare_ifds_csr_resident_direct_via(&dispatch, 1, 1, 1, &[(0, 0, 0)], &[], &[], &[])
.expect("direct resident prepare must build a minimal resident CSR");
assert_eq!(
dispatch.upload_batch_lens.borrow().as_slice(),
&[17],
"Fix: direct-resident IFDS prepare must upload fixed CSR inputs and generated zero CSR buffers as one logical staging batch."
);
assert_eq!(
dispatch.dispatch_resource_lens.borrow().as_slice(),
&[17, 3],
"Fix: direct-resident IFDS prepare must keep CSR build and metadata fill as the only resident dispatches."
);
assert!(
prepared.pg_nodes != prepared.pg_node_tags,
"Fix: direct-resident metadata buffers are written independently and must not alias unless the fill kernel contract changes."
);
}
#[test]
fn direct_resident_prepare_split_phase_has_no_production_panic_path() {
let source = include_str!("ifds_resident_direct_prepare.rs");
let production = source
.split("#[cfg(test)]")
.next()
.expect("direct resident prepare source must contain production section");
assert!(
!production.contains(concat!("panic", "!("))
&& !production.contains(".unwrap_or_else(")
&& !production.contains(".expect("),
"Fix: direct-resident IFDS prepare production path must return typed errors before resident allocation instead of panicking."
);
assert!(
production.contains("split_columns_into(")
&& production.contains(") -> Result<(), String>"),
"Fix: direct-resident IFDS edge-column split must propagate checked capacity failures."
);
}
}