feat(core): GPU-offload clamp with per-workload floor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,7 +59,13 @@ pub fn inference_thread_count(workload: Workload, gpu_offloaded: bool) -> usize
|
||||
if power::probe_power_state() == PowerState::OnBattery {
|
||||
chosen /= 2;
|
||||
}
|
||||
let _ = (workload, gpu_offloaded); // GPU clamp added in next task
|
||||
if gpu_offloaded {
|
||||
let floor = match workload {
|
||||
Workload::Llm => GPU_FLOOR_LLM,
|
||||
Workload::Whisper => GPU_FLOOR_WHISPER,
|
||||
};
|
||||
chosen = chosen.min(floor);
|
||||
}
|
||||
chosen.clamp(MIN_INFERENCE_THREADS, MAX_INFERENCE_THREADS)
|
||||
}
|
||||
|
||||
@@ -128,4 +134,52 @@ mod tests {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gpu_offload_clamps_llm_to_floor() {
|
||||
with_thread_env_lock(|| {
|
||||
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
||||
crate::power::with_override(Some(PowerState::OnAc), || {
|
||||
let n = inference_thread_count(Workload::Llm, true);
|
||||
assert!(n <= GPU_FLOOR_LLM.max(MIN_INFERENCE_THREADS),
|
||||
"Llm with GPU offload should clamp to {GPU_FLOOR_LLM}, got {n}");
|
||||
assert!(n >= MIN_INFERENCE_THREADS);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gpu_offload_clamps_whisper_to_floor() {
|
||||
with_thread_env_lock(|| {
|
||||
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
||||
crate::power::with_override(Some(PowerState::OnAc), || {
|
||||
let n = inference_thread_count(Workload::Whisper, true);
|
||||
// Whisper floor is 4 on machines with >=4 physical cores;
|
||||
// can't go lower than physical so on a 2c host we stay at 2.
|
||||
assert!(n <= GPU_FLOOR_WHISPER, "got {n}");
|
||||
assert!(n >= MIN_INFERENCE_THREADS);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn whisper_gpu_floor_is_at_least_llm_gpu_floor() {
|
||||
// Architectural invariant: whisper retains CPU work even when
|
||||
// GPU-offloaded; its floor must not be lower than the LLM's.
|
||||
assert!(GPU_FLOOR_WHISPER >= GPU_FLOOR_LLM);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gpu_offload_off_does_not_clamp_below_battery_calc() {
|
||||
with_thread_env_lock(|| {
|
||||
std::env::remove_var("MAGNOTIA_INFERENCE_THREADS");
|
||||
// Sequential measurements; with_override is non-reentrant.
|
||||
crate::power::with_override(Some(PowerState::OnAc), || {
|
||||
let no_gpu = inference_thread_count(Workload::Llm, false);
|
||||
let with_gpu = inference_thread_count(Workload::Llm, true);
|
||||
// GPU-offloaded should be <= non-offloaded.
|
||||
assert!(with_gpu <= no_gpu);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user