use super::layout::{assert_whole_units, plan_unit_tasks};
use crate::ops::shards::ChunkShards;
use crate::policy::ExecutionPolicy;
use moirai_executor::{SyncTask, global};
pub(super) fn drive_unit_tasks<P, B, S, Init, F>(
buffers: B,
unit_len: usize,
unit_bytes: usize,
context: &'static str,
init: Init,
f: F,
) where
P: ExecutionPolicy,
B: ChunkShards,
Init: Fn() -> S + Send + Sync,
F: Fn(&mut S, usize, B::Chunk) + Send + Sync,
{
let len = buffers.len();
assert_whole_units(len, unit_len);
let Some(plan) = plan_unit_tasks::<P>(len, unit_len, unit_bytes) else {
return;
};
let views = buffers.split(plan.task_len);
if !plan.parallel {
let mut state = init();
for task in 0..plan.tasks {
let chunk = unsafe { B::chunk(&views, task) };
f(&mut state, task * plan.per_task, chunk);
}
return;
}
let (init, f) = (&init, &f);
global()
.for_each_indexed::<SyncTask, _>(plan.tasks, move |task| {
let chunk = unsafe { B::chunk(&views, task) };
let mut state = init();
f(&mut state, task * plan.per_task, chunk);
})
.expect(context);
}