use crate::device_ext::{available_devices, fastest_among};
use rlx_driver::Device;
use rlx_hwprofile::{BackendKind, HostProfile};
pub use rlx_hwprofile::{GpuInfo, HostProfile as Profile, detect};
fn device_backend(device: Device) -> Option<BackendKind> {
match device {
Device::Cuda => Some(BackendKind::Cuda),
Device::Rocm => Some(BackendKind::Rocm),
Device::Metal | Device::Mlx | Device::Ane => Some(BackendKind::Metal),
Device::Vulkan => Some(BackendKind::Vulkan),
Device::Cpu => Some(BackendKind::Cpu),
_ => None,
}
}
fn device_vram_bytes_in(profile: &HostProfile, device: Device) -> Option<u64> {
let backend = device_backend(device)?;
profile
.gpus
.iter()
.filter(|g| g.backend == backend && g.vram_bytes > 0)
.map(|g| g.vram_bytes)
.max()
}
pub fn device_vram_bytes(device: Device) -> Option<u64> {
device_vram_bytes_in(&detect(), device)
}
pub fn fastest_device_with_vram(min_vram_bytes: u64) -> Device {
let profile = detect();
let fits = |d: Device| match device_vram_bytes_in(&profile, d) {
Some(v) => v >= min_vram_bytes,
None => true,
};
let candidates: Vec<Device> = available_devices()
.into_iter()
.filter(|&d| fits(d))
.collect();
if candidates.is_empty() {
return Device::Cpu;
}
fastest_among(&candidates)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn detect_and_select_never_panics() {
let profile = detect();
assert!(!profile.available_backends.is_empty());
let d = fastest_device_with_vram(1 << 30); let _ = device_backend(d);
}
}