use super::{artifacts::Part, options::Batching};
use crate::ComputeUnits;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PlacementTable<T> {
cpu_only: T,
cpu_and_gpu: T,
cpu_and_neural_engine: T,
all: T,
}
impl<T: Copy> PlacementTable<T> {
#[inline]
pub const fn unmeasured(value: T) -> Self {
Self {
cpu_only: value,
cpu_and_gpu: value,
cpu_and_neural_engine: value,
all: value,
}
}
#[must_use]
#[inline]
pub const fn with(self, units: ComputeUnits, value: T) -> Self {
let mut table = self;
match units {
ComputeUnits::CpuOnly => table.cpu_only = value,
ComputeUnits::CpuAndGpu => table.cpu_and_gpu = value,
ComputeUnits::CpuAndNeuralEngine => table.cpu_and_neural_engine = value,
ComputeUnits::All => table.all = value,
}
table
}
#[inline]
pub const fn get(&self, units: ComputeUnits) -> T {
match units {
ComputeUnits::CpuOnly => self.cpu_only,
ComputeUnits::CpuAndGpu => self.cpu_and_gpu,
ComputeUnits::CpuAndNeuralEngine => self.cpu_and_neural_engine,
ComputeUnits::All => self.all,
}
}
}
pub const PACKED_SLOT_INVARIANT: PlacementTable<bool> = PlacementTable::unmeasured(false);
const TEXT_RUN_IDENTITY: PlacementTable<Option<bool>> = PlacementTable::unmeasured(None)
.with(ComputeUnits::CpuOnly, Some(true))
.with(ComputeUnits::CpuAndGpu, Some(true))
.with(ComputeUnits::CpuAndNeuralEngine, Some(true))
.with(ComputeUnits::All, Some(true));
const AUDIO_RUN_IDENTITY: PlacementTable<Option<bool>> = PlacementTable::unmeasured(None)
.with(ComputeUnits::CpuOnly, Some(true))
.with(ComputeUnits::CpuAndGpu, Some(true))
.with(ComputeUnits::CpuAndNeuralEngine, Some(true))
.with(ComputeUnits::All, Some(true));
const VISION_RUN_IDENTITY: PlacementTable<Option<bool>> = PlacementTable::unmeasured(None)
.with(ComputeUnits::CpuOnly, Some(true))
.with(ComputeUnits::CpuAndGpu, Some(true))
.with(ComputeUnits::CpuAndNeuralEngine, Some(true))
.with(ComputeUnits::All, Some(true));
#[inline]
pub const fn run_identity(part: Part, units: ComputeUnits) -> Option<bool> {
match part {
Part::Text => TEXT_RUN_IDENTITY.get(units),
Part::Audio => AUDIO_RUN_IDENTITY.get(units),
Part::Vision => VISION_RUN_IDENTITY.get(units),
}
}
impl Batching {
#[inline]
pub const fn batch_independent(self, units: ComputeUnits) -> bool {
self.batch_independent_in(units, &PACKED_SLOT_INVARIANT)
}
#[inline]
pub(crate) const fn batch_independent_in(
self,
units: ComputeUnits,
table: &PlacementTable<bool>,
) -> bool {
match self {
Self::Single => true,
Self::Packed => table.get(units),
}
}
}
#[cfg(test)]
mod tests;