Merge amd-clock-25 2ab55388 into release-0.3.25 (the integrated Radeon's dash-only tune line reads not available; the 9070 XT's real line gives the knob)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-08 09:20:30 +00:00
commit bf3eefb3c3
2 changed files with 24 additions and 0 deletions

View file

@ -1292,6 +1292,11 @@ pub fn amd_knob(shape: Option<&AmdTuneShape>, gclk_now_mhz: f64, linux: bool) ->
if linux {
return Err("not available (Linux: the clock and power limits under /sys need root; the tune's helper takes them in a later cut)".into());
}
// PC 1's integrated Radeon (8 October 2026, the exe's read-back): `gmax - gmax_range - - plimit - plimit_range - - factory 0 ok`,
// every field a dash (-1 after the parser), an ok line with no tuning interface behind it
if t.gmax_max <= t.gmax_min && t.plimit_max <= t.plimit_min {
return Err("not available (the driver exposes no tuning interface for this card: the tune line carries no clock or power range)".into());
}
if t.plimit_max < t.plimit_min || t.plimit_min <= -100.0 {
return Err(format!("not available (the power-limit range {} to {} percent is not usable)", t.plimit_min, t.plimit_max));
}
@ -1358,6 +1363,11 @@ mod tests {
assert!(e.contains("stock clock is not known until the card mines"), "{e}");
let e = amd_knob(Some(&t9070()), 2970.0, true).unwrap_err();
assert!(e.starts_with("not available (Linux"), "{e}");
// the integrated Radeon's line on PC 1 (8 October 2026): ok, every range a dash; known-failed first (it read as an
// offset knob with a one-MHz ladder and a 99 percent power range)
let igpu = AmdTuneShape { ok: true, error: String::new(), gmax: -1.0, gmax_min: -1.0, gmax_max: -1.0, plimit_min: -1.0, plimit_max: -1.0 };
let e = amd_knob(Some(&igpu), 2100.0, false).unwrap_err();
assert!(e.starts_with("not available (the driver exposes no tuning interface"), "{e}");
assert!(control_reason("amd", &Limits::default(), "amd:gfx1201", true, false).unwrap().contains("not available ("));
}

View file

@ -6034,6 +6034,20 @@ mod tests {
assert!(guard < elevated, "the Windows return comes before the unix elevated step");
}
/// The two tune lines PC 1 answered on 8 October 2026 (igneum-gpu-telemetry 1d8e055d, the AMD knob's tool): the
/// integrated Radeon with no interface reads "not available", the RX 9070 XT reads the offset knob.
#[test]
fn pc1s_two_tune_lines_give_one_refusal_and_one_knob() {
let igpu = super::parse_amd_tune("tune 0 name \"AMD Radeon(TM) Graphics\" gmax - gmax_range - - plimit - plimit_range - - factory 0 ok").unwrap();
assert!(igpu.ok && igpu.gmax_max < 0.0 && igpu.plimit_max < 0.0, "{igpu:?}");
let shape = |t: &super::AmdTune| crate::ember::AmdTuneShape { ok: t.ok, error: t.error.clone(), gmax: t.gmax, gmax_min: t.gmax_min, gmax_max: t.gmax_max, plimit_min: t.plimit_min, plimit_max: t.plimit_max };
assert!(crate::ember::amd_knob(Some(&shape(&igpu)), 2100.0, false).unwrap_err().contains("no tuning interface"));
let xt = super::parse_amd_tune("tune 1 name \"AMD Radeon RX 9070 XT\" gmax 0 gmax_range -500 1000 plimit 0 plimit_range -30 10 factory 1 ok").unwrap();
let k = crate::ember::amd_knob(Some(&shape(&xt)), 3292.0, false).unwrap();
assert_eq!((k.stock_mhz, k.gmax_offset, k.clock_max_mhz, k.clock_min_mhz, k.plimit_min, k.plimit_max), (3292, true, 3292, 2792, -30.0, 10.0), "the live clock under load (3,292 MHz in the read-back sample) is the stock the offsets apply to");
assert_eq!(crate::ember::amd_gmax_arg(2992, 3292, true), -300);
}
/// PC 2, 7 October 2026, 14:39Z: "the helper did not run sequence 1 within 15 s (no line in ...helper.log)" is a FAULT line
#[test]
fn a_helper_that_does_not_answer_is_a_fault_line() {