ember: the AMD helper's gmax range is an offset from stock (PC 1's 9070 XT: -500 to 1000), not MHz: the clock knob stays closed on an offset range and the power ladder is bounded by plimit_range (-30 to 10) on a percent scale
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
dd37094a5b
commit
794e23c5ac
1 changed files with 22 additions and 8 deletions
|
|
@ -1891,13 +1891,13 @@ impl Engine {
|
|||
None if allowed || current > 0 => crate::detect::run_timeout(std::process::Command::new(&smi).args(["-i", &device, "-pl", ¤t.to_string()]), None, Duration::from_secs(20)).map(|out| out.contains("All done")),
|
||||
None => Some(false),
|
||||
};
|
||||
shared.send(Cmd::TuneProbe(idx, Ok(TuneProbe { clock_max_mhz: clock_max, clock_min_mhz: 0, driver, direct: direct.unwrap_or(false), amd_ordinal: -1 })));
|
||||
shared.send(Cmd::TuneProbe(idx, Ok(TuneProbe { clock_max_mhz: clock_max, clock_min_mhz: 0, driver, direct: direct.unwrap_or(false), amd_ordinal: -1, ..Default::default() })));
|
||||
});
|
||||
}
|
||||
"amd" => {
|
||||
let Some(exe) = self.bins.telemetry.clone() else {
|
||||
self.sweep_pending = None;
|
||||
self.shared.send(Cmd::TuneProbe(idx, Ok(TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver: c.driver.clone(), direct: false, amd_ordinal: -1 })));
|
||||
self.shared.send(Cmd::TuneProbe(idx, Ok(TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver: c.driver.clone(), direct: false, amd_ordinal: -1, ..Default::default() })));
|
||||
return;
|
||||
};
|
||||
let ordinal = c.amd_ordinal;
|
||||
|
|
@ -1906,14 +1906,18 @@ impl Engine {
|
|||
let out = crate::detect::run_timeout(std::process::Command::new(&exe).arg("--tune"), None, Duration::from_secs(20)).unwrap_or_default();
|
||||
let t = out.lines().filter_map(parse_amd_tune).find(|t| ordinal < 0 || t.ordinal as i64 == ordinal);
|
||||
shared.send(Cmd::TuneProbe(idx, Ok(match t {
|
||||
Some(t) if t.ok => TuneProbe { clock_max_mhz: t.gmax_max as u32, clock_min_mhz: t.gmax_min as u32, driver, direct: true, amd_ordinal: t.ordinal as i64 },
|
||||
Some(t) => TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver, direct: false, amd_ordinal: t.ordinal as i64 },
|
||||
None => TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver, direct: false, amd_ordinal: -1 },
|
||||
// PC 1's 9070 XT (ember-tune-pc1-1, 22:30 UTC): `gmax 0 gmax_range -500 1000`, an OFFSET from
|
||||
// the stock clock, not MHz; a range with a negative floor is an offset range and the clock
|
||||
// knob stays closed until the stock clock is known (the power limit is the AMD lever), and
|
||||
// `plimit_range -30 10` bounds the power ladder (the percent scale rides power_* below)
|
||||
Some(t) if t.ok => TuneProbe { clock_max_mhz: if t.gmax_min >= 0.0 && t.gmax_max > 0.0 { t.gmax_max as u32 } else { 0 }, clock_min_mhz: if t.gmax_min > 0.0 { t.gmax_min as u32 } else { 0 }, driver, direct: true, amd_ordinal: t.ordinal as i64, plimit_min: t.plimit_min, plimit_max: t.plimit_max },
|
||||
Some(t) => TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver, direct: false, amd_ordinal: t.ordinal as i64, ..Default::default() },
|
||||
None => TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver, direct: false, amd_ordinal: -1, ..Default::default() },
|
||||
})));
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
self.shared.send(Cmd::TuneProbe(idx, Ok(TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver: c.driver.clone(), direct: false, amd_ordinal: -1 })));
|
||||
self.shared.send(Cmd::TuneProbe(idx, Ok(TuneProbe { clock_max_mhz: 0, clock_min_mhz: 0, driver: c.driver.clone(), direct: false, amd_ordinal: -1, ..Default::default() })));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1939,7 +1943,13 @@ impl Engine {
|
|||
// NVIDIA control: this process is elevated (direct), or Power control is on so the one-prompt helper may run.
|
||||
// The --sweep job alone never counts: it must not raise a prompt on a PC with nobody there (5 October 2026).
|
||||
let power_control = probe.direct || self.shared.settings.lock().unwrap().power_control;
|
||||
let limits = crate::ember::Limits { power_default_w: c.power_default_w, power_min_w: c.power_min_w, power_max_w: c.power_max_w, clock_max_mhz: probe.clock_max_mhz, clock_min_mhz: probe.clock_min_mhz };
|
||||
// AMD's power limit is a percent offset from the default (ADLX): the plan's watts scale becomes a percent
|
||||
// scale (default 100, floor 100 + plimit_min, ceiling 100 + plimit_max), tune_apply sends pct - 100
|
||||
let limits = if c.vendor == "amd" && probe.direct && probe.plimit_max >= probe.plimit_min && probe.plimit_min > -100.0 {
|
||||
crate::ember::Limits { power_default_w: 100.0, power_min_w: 100.0 + probe.plimit_min, power_max_w: 100.0 + probe.plimit_max, clock_max_mhz: probe.clock_max_mhz, clock_min_mhz: probe.clock_min_mhz }
|
||||
} else {
|
||||
crate::ember::Limits { power_default_w: c.power_default_w, power_min_w: c.power_min_w, power_max_w: c.power_max_w, clock_max_mhz: probe.clock_max_mhz, clock_min_mhz: probe.clock_min_mhz }
|
||||
};
|
||||
let control = match c.vendor.as_str() {
|
||||
"nvidia" => crate::ember::control_reason("nvidia", &limits, &c.device, power_control, false),
|
||||
"amd" => crate::ember::control_reason("amd", &limits, &c.device, power_control, probe.direct && probe.amd_ordinal >= 0),
|
||||
|
|
@ -2113,7 +2123,8 @@ impl Engine {
|
|||
return;
|
||||
}
|
||||
let n = c.amd_ordinal.to_string();
|
||||
let offset = step.point.power_pct as i64 - 100;
|
||||
// the step's limit on the AMD scale is a percent (the probe's Limits); the offset is that minus 100
|
||||
let offset = if c.power_default_w <= 0.0 { step.watts.round() as i64 - 100 } else { step.point.power_pct as i64 - 100 };
|
||||
let unlocked = clock == 0 && offset == 0;
|
||||
let gmax = if clock > 0 { clock } else { c.clock_max_mhz };
|
||||
std::thread::spawn(move || {
|
||||
|
|
@ -3465,6 +3476,9 @@ pub struct TuneProbe {
|
|||
/// NVIDIA: this process sets limits itself (elevated); AMD: the helper answered its `--tune` line with ok
|
||||
pub direct: bool,
|
||||
pub amd_ordinal: i64,
|
||||
/// AMD: the power offset range in percent from the `tune` line (PC 1's 9070 XT: -30 to 10)
|
||||
pub plimit_min: f64,
|
||||
pub plimit_max: f64,
|
||||
}
|
||||
|
||||
/// One `tune` line of igneum-gpu-telemetry --tune:
|
||||
|
|
|
|||
Loading…
Reference in a new issue