use rlx_runtime::Device;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MetalGgufPrefillMode {
#[default]
Auto,
CpuF32,
PackedGguf,
MetalF32,
}
impl MetalGgufPrefillMode {
pub fn parse(s: &str) -> Option<Self> {
match s.trim().to_ascii_lowercase().as_str() {
"auto" => Some(Self::Auto),
"cpu" | "cpu_f32" | "f32" => Some(Self::CpuF32),
"packed" | "packed_gguf" | "gguf" => Some(Self::PackedGguf),
"metal" | "metal_f32" => Some(Self::MetalF32),
_ => None,
}
}
pub fn resolve(self) -> Self {
if self != Self::Auto {
return self;
}
if matches!(
rlx_ir::env::var("RLX_METAL_F32_PREFILL_CPU").as_deref(),
Some("1") | Some("true") | Some("TRUE")
) {
return Self::CpuF32;
}
if matches!(
rlx_ir::env::var("RLX_METAL_PACKED_PREFILL").as_deref(),
Some("1") | Some("true") | Some("TRUE")
) {
return Self::PackedGguf;
}
if matches!(
rlx_ir::env::var("RLX_METAL_F32_PREFILL_CPU").as_deref(),
Some("0") | Some("false") | Some("FALSE")
) {
return Self::MetalF32;
}
Self::CpuF32
}
pub fn use_packed_gguf(self) -> bool {
matches!(self.resolve(), Self::PackedGguf)
}
pub fn prefill_device(self, inference_device: Device) -> Device {
match inference_device {
Device::Metal => match self.resolve() {
Self::PackedGguf | Self::MetalF32 => Device::Metal,
Self::CpuF32 | Self::Auto => Device::Cpu,
},
Device::Gpu | Device::Vulkan => Device::Cpu,
other => other,
}
}
}
pub fn metal_use_packed_gguf_prefill() -> bool {
MetalGgufPrefillMode::Auto.use_packed_gguf()
}
pub fn prefill_device_for(device: Device) -> Device {
MetalGgufPrefillMode::Auto.prefill_device(device)
}