use super::thresholds;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum GpuTier {
High,
Mid,
Low,
}
const GPU_TIER_COUNT: usize = 3;
#[must_use]
pub(crate) fn classify_gpu_tier(adapter_name: Option<&str>) -> GpuTier {
let Some(name) = adapter_name else {
return GpuTier::Low;
};
let lower = name.to_ascii_lowercase();
if lower.contains("rtx 40")
|| lower.contains("rtx 50")
|| lower.contains("a100")
|| lower.contains("h100")
|| lower.contains("h200")
|| lower.contains("rx 7900 xtx")
|| lower.contains("rx 7900 xt")
|| lower.contains("m4 max")
|| lower.contains("m3 max")
|| lower.contains("m2 max")
|| lower.contains("m1 max")
|| lower.contains("m4 ultra")
|| lower.contains("m3 ultra")
|| lower.contains("m2 ultra")
|| lower.contains("m1 ultra")
{
return GpuTier::High;
}
if lower.contains("rtx 20")
|| lower.contains("rtx 30")
|| lower.contains("gtx 16")
|| lower.contains("arc")
|| lower.contains("rx 6")
|| lower.contains("rx 7")
|| lower.contains("apple m1")
|| lower.contains("apple m2")
|| lower.contains("apple m3")
|| lower.contains("apple m4")
|| lower.contains("m1 pro")
|| lower.contains("m2 pro")
|| lower.contains("m3 pro")
|| lower.contains("m4 pro")
{
return GpuTier::Mid;
}
GpuTier::Low
}
#[must_use]
pub(crate) fn gpu_min_bytes_for_tier(tier: GpuTier) -> u64 {
match tier {
GpuTier::High => thresholds::GPU_MIN_BYTES_HIGH_TIER,
GpuTier::Mid => thresholds::GPU_MIN_BYTES_MID_TIER,
GpuTier::Low => thresholds::GPU_MIN_BYTES,
}
}
#[must_use]
pub(crate) fn gpu_solo_bytes_for_tier(tier: GpuTier) -> u64 {
match tier {
GpuTier::High => thresholds::GPU_BYTES_BREAKEVEN_SOLO_HIGH_TIER,
GpuTier::Mid => thresholds::GPU_BYTES_BREAKEVEN_SOLO_MID_TIER,
GpuTier::Low => thresholds::GPU_BYTES_BREAKEVEN_SOLO,
}
}
#[must_use]
pub(crate) fn gpu_pattern_breakeven_for_tier(tier: GpuTier) -> usize {
match tier {
GpuTier::High => thresholds::GPU_PATTERN_BREAKEVEN_HIGH_TIER,
GpuTier::Mid => thresholds::GPU_PATTERN_BREAKEVEN_MID_TIER,
GpuTier::Low => thresholds::GPU_PATTERN_BREAKEVEN,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GpuRoutingProfile {
pub tier: &'static str,
pub description: &'static str,
pub min_bytes: u64,
pub solo_bytes: u64,
pub pattern_breakeven: usize,
}
#[must_use]
pub fn gpu_routing_profile(adapter_name: Option<&str>) -> GpuRoutingProfile {
profile_for_tier(classify_gpu_tier(adapter_name))
}
#[must_use]
pub fn gpu_routing_profiles() -> [GpuRoutingProfile; GPU_TIER_COUNT] {
[
profile_for_tier(GpuTier::High),
profile_for_tier(GpuTier::Mid),
profile_for_tier(GpuTier::Low),
]
}
fn profile_for_tier(tier: GpuTier) -> GpuRoutingProfile {
let (label, description) = match tier {
GpuTier::High => ("high", "RTX 40/50, A100/H100, M-Max"),
GpuTier::Mid => ("mid", "RTX 20/30, GTX 16, Arc, M-Pro/base"),
GpuTier::Low => ("low", "low / unknown"),
};
GpuRoutingProfile {
tier: label,
description,
min_bytes: gpu_min_bytes_for_tier(tier),
solo_bytes: gpu_solo_bytes_for_tier(tier),
pattern_breakeven: gpu_pattern_breakeven_for_tier(tier),
}
}