use std::collections::{HashMap, HashSet};
use crate::backend::BackendError;
mod barrier_split;
mod host_dispatch;
mod let_propagation;
mod live_buffers;
mod resident_dispatch;
mod segment_buffers;
#[cfg(test)]
mod test_programs;
pub use barrier_split::{contains_grid_sync, split_on_grid_sync, try_split_on_grid_sync};
pub use host_dispatch::{
dispatch_with_grid_sync_split, dispatch_with_grid_sync_split_into,
dispatch_with_grid_sync_split_timed, dispatch_with_grid_sync_split_via,
dispatch_with_grid_sync_split_via_into,
};
pub use resident_dispatch::{
dispatch_resident_grid_sync_fixpoint_into, dispatch_resident_with_grid_sync_split_timed,
};
pub use segment_buffers::plan_host_grid_sync_segment_programs;
fn reserve_grid_sync_vec<T>(
vec: &mut Vec<T>,
capacity: usize,
field: &'static str,
) -> Result<(), BackendError> {
crate::allocation::try_reserve_vec_to_capacity(vec, capacity).map_err(|error| {
BackendError::InvalidProgram {
fix: format!(
"Fix: failed to reserve {field} for {capacity} entries during grid-sync dispatch splitting: {error}. Split the program into fewer grid-sync segments or run on a backend with native grid sync."
),
}
})
}
fn reserve_grid_sync_hash_map<K, V>(
map: &mut HashMap<K, V>,
capacity: usize,
field: &'static str,
) -> Result<(), BackendError>
where
K: Eq + std::hash::Hash,
{
map.try_reserve(capacity)
.map_err(|error| BackendError::InvalidProgram {
fix: format!(
"Fix: failed to reserve {field} for {capacity} entries during grid-sync dispatch splitting: {error}. Split the program into fewer grid-sync segments or run on a backend with native grid sync."
),
})
}
fn reserve_grid_sync_hash_set<T>(
set: &mut HashSet<T>,
capacity: usize,
field: &'static str,
) -> Result<(), BackendError>
where
T: Eq + std::hash::Hash,
{
set.try_reserve(capacity)
.map_err(|error| BackendError::InvalidProgram {
fix: format!(
"Fix: failed to reserve {field} for {capacity} entries during grid-sync dispatch splitting: {error}. Split the program into fewer grid-sync segments or run on a backend with native grid sync."
),
})
}
fn grid_sync_segment_error(
error: BackendError,
segment_idx: usize,
segment_count: usize,
) -> BackendError {
match error {
BackendError::InvalidProgram { fix } => BackendError::InvalidProgram {
fix: format!(
"Fix: grid-sync split segment {segment_idx} of {segment_count} dispatch failed: {fix}"
),
},
other => other,
}
}
fn elapsed_wall_ns(started: std::time::Instant) -> Result<u64, BackendError> {
u64::try_from(started.elapsed().as_nanos()).map_err(|error| BackendError::InvalidProgram {
fix: format!(
"Fix: grid-sync segmented wall timing cannot fit u64 nanoseconds: {error}. Split telemetry windows or report per-segment timing."
),
})
}