Ember playbook: the AMD watts source. The script samples the installed app's /api/state power_w for the AMD card every 10 s (a GET), counts the engine's own AMD watts, prints a fallback ladder (median per step, with the step's MH/s and MH/W) when the engine's AMD progress carries no watts, and names the source it used

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-06 16:00:09 +00:00
parent 28b28d81b7
commit 94a7109d5c

View file

@ -174,8 +174,21 @@ function Exit3([string] $why, [string] $reason) {
Write-Output 'RESULT TUNE error=no_rows'
exit 3
}
# the AMD watts source (coordinator, 6 October 2026 16:00Z): the 3.0 coordinator's job read ZERO watts for the 9070 XT
# from igneum-gpu-telemetry.exe while the installed app had read 198.9 W the day before. The tune engine samples its
# own helper; this script also samples the installed app's /api/state power_w for the AMD card every 10 s (a GET,
# never a write) and, when the engine's AMD progress lines carry no watts, prints a fallback ladder from those
# samples (median per step) and names the source it used
$amdApp = @(); $amdStep = 0; $amdMhs = 0.0; $amdEngNZ = 0; $amdEngZ = 0; $tick = 0; $amdMhsByStep = @{}
while (-not $p.HasExited) {
Start-Sleep -Seconds 5
$tick++
if ($installedUrl -and ($tick % 2 -eq 0)) {
try {
$js = (Invoke-WebRequest -Uri ($installedUrl + 'api/state') -UseBasicParsing -TimeoutSec 3).Content | ConvertFrom-Json
foreach ($c in @($js.mining.cards)) { if ($c.vendor -eq 'amd') { $amdApp += ,@{ step = $amdStep; w = [double]$c.power_w } } }
} catch { }
}
$tailLine = EngineTail
if ($tailLine) { $lastEngineLine = $tailLine }
$statusLine = EngineStatus
@ -191,7 +204,12 @@ while (-not $p.HasExited) {
$all = @(); if (Test-Path -LiteralPath $outFile) { $all = @(Get-Content -LiteralPath $outFile -ErrorAction SilentlyContinue) }
while ($seen -lt $all.Count) {
$l = [string]$all[$seen]; $seen++
if ($l -match '^TUNE progress ') { Forward $l }
if ($l -match '^TUNE progress ') {
Forward $l
if ($l -match ' key=amd' -and $l -match ' step=(\d+)') { $amdStep = [int]$Matches[1]
if ($l -match ' mhs=([\d.]+)') { $amdMhsByStep[$amdStep] = [double]::Parse($Matches[1], [Globalization.CultureInfo]::InvariantCulture) }
if ($l -match ' watts=([\d.]+)' -and [double]::Parse($Matches[1], [Globalization.CultureInfo]::InvariantCulture) -gt 0) { $amdEngNZ++ } else { $amdEngZ++ } }
}
elseif ($l -match '^TUNE ') { Write-Output ('RESULT ' + $l); if ($l -match '^TUNE card=') { $rows++ }; if ($l -match '^TUNE chosen ') { Forward $l } }
elseif ($l -match '^SWEEP ') { Write-Output ('RESULT ' + $l) }
elseif ($l -match '^(URL|STATE) ') { }
@ -217,6 +235,20 @@ while (-not $p.HasExited) {
}
$all = @(); if (Test-Path -LiteralPath $outFile) { $all = @(Get-Content -LiteralPath $outFile -ErrorAction SilentlyContinue) }
while ($seen -lt $all.Count) { $l = [string]$all[$seen]; $seen++; if ($l -match '^TUNE ') { Write-Output ('RESULT ' + $l); if ($l -match '^TUNE card=') { $rows++ } } }
$amdNZ = @($amdApp | Where-Object { $_.w -gt 0 })
Write-Output ('RESULT TUNE amd_watts engine_progress nonzero=' + $amdEngNZ + ' zero=' + $amdEngZ + ' app_state samples=' + $amdApp.Count + ' nonzero=' + $amdNZ.Count)
$amdSource = 'none'
if ($amdEngNZ -gt 0) { $amdSource = 'engine_telemetry' }
elseif ($amdNZ.Count -gt 0) {
$amdSource = 'app_state_fallback'
foreach ($g in ($amdNZ | Group-Object { $_.step } | Sort-Object { [int]$_.Name })) {
$ws = @($g.Group | ForEach-Object { $_.w } | Sort-Object); $med = $ws[[int][math]::Floor($ws.Count / 2)]
$mh = 0.0; if ($amdMhsByStep.ContainsKey([int]$g.Name)) { $mh = $amdMhsByStep[[int]$g.Name] }
$eff = 0.0; if ($med -gt 0) { $eff = $mh / $med }
Write-Output ('RESULT TUNE amd_fallback source=app_state step=' + $g.Name + ' watts=' + ('{0:F1}' -f $med) + ' mhs=' + ('{0:F2}' -f $mh) + ' eff=' + ('{0:F4}' -f $eff) + ' samples=' + $ws.Count)
}
}
Write-Output ('RESULT TUNE amd_watts_source=' + $amdSource)
Say ("tune engine exited " + $p.ExitCode + " after " + [int]((Get-Date) - $started).TotalSeconds + " s, " + $rows + " table rows")
EndTree $p.Id 'end of run'
# the project lead, 6 October 2026, 07:25Z: both cards stay on their best MH/W points (the tune pins them); no factory reset here.