use crate::ifds_resident_types::{
IfdsResidentDispatch, ResidentIfdsScratch, ResidentPreparedIfdsCsr,
};
pub fn allocate_resident_ifds_scratch<D>(
dispatch: &D,
prepared: &ResidentPreparedIfdsCsr<D::Resource>,
) -> Result<ResidentIfdsScratch<D::Resource>, String>
where
D: IfdsResidentDispatch,
{
allocate_resident_ifds_scratch_with_seed_capacity(dispatch, prepared, 1)
}
pub fn allocate_resident_ifds_scratch_with_seed_capacity<D>(
dispatch: &D,
prepared: &ResidentPreparedIfdsCsr<D::Resource>,
max_seed_facts: usize,
) -> Result<ResidentIfdsScratch<D::Resource>, String>
where
D: IfdsResidentDispatch,
{
if max_seed_facts == 0 {
return Err(
"weir IFDS resident scratch seed capacity must be positive. Fix: allocate at least one staged seed fact or skip solving empty seed batches."
.to_string(),
);
}
let frontier_byte_len = prepared
.words
.checked_mul(std::mem::size_of::<u32>())
.ok_or_else(|| {
"weir IFDS resident scratch frontier byte length overflows usize. Fix: shard the IFDS problem before resident solving.".to_string()
})?;
let changed_byte_len = std::mem::size_of::<u32>();
let retained_byte_len = frontier_byte_len
.checked_add(changed_byte_len)
.ok_or_else(|| {
"weir IFDS resident scratch retained byte accounting overflows usize. Fix: shard the IFDS problem before resident solving.".to_string()
})?;
let frontier = dispatch
.allocate_resident(frontier_byte_len)
.map_err(|error| format!("weir IFDS resident allocate scratch frontier failed: {error}"))?;
let changed = match dispatch.allocate_resident(changed_byte_len) {
Ok(resource) => resource,
Err(error) => {
let _ = super::free_unique_resident_resources(dispatch, [("frontier", frontier)]);
return Err(format!(
"weir IFDS resident allocate scratch changed flag failed: {error}"
));
}
};
Ok(ResidentIfdsScratch {
words: prepared.words,
max_seed_facts,
frontier_byte_len,
changed_byte_len,
retained_byte_len,
frontier,
changed,
})
}
pub fn free_resident_ifds_scratch<D>(
dispatch: &D,
scratch: ResidentIfdsScratch<D::Resource>,
) -> Result<(), String>
where
D: IfdsResidentDispatch,
{
let ResidentIfdsScratch {
frontier, changed, ..
} = scratch;
super::free_unique_resident_resources(
dispatch,
[
("scratch frontier", frontier),
("scratch changed flag", changed),
],
)
}