igneum/tools/ca3-pc1-amd/pc1-amd-family.ps1

146 lines
12 KiB
PowerShell

# Counter ASIC 3.0, PC 1 AMD job 2 (6 October 2026, run e: the 9070 XT ALONE): item 6's step cost of every reserve candidate family of spec
# 1.13.2 on PC 1's RX 9070 XT (machine ae432dc7, gfx1201), docs/plans/counter-asic-3-reserve.md, status file section
# 3 "Item 6" (the OWED AMD column). Run a (run-ca3-pc1-amd-family-20261006, 150 s, exit 0) measured ordinal 0, PC 1's
# integrated gfx1036 (one CU: alu 40.59 G steps/s against the 9070 XT's expected 1,000 to 2,000): the device list parse
# ran a second -match after the capturing one, which overwrote $Matches, so every device read idx 0 and an empty name,
# and the probe took a bare ordinal. Run b: the probe picks the card BY NAME (`--device-name gfx1201`, the match on the
# newest AMD platform by driver version, the kit worker's dedup rule; `RESULT device_choice name= index= platform= driver=
# cus=`), prints the device's name, CUs and platform on every RESULT line, and refuses with `RESULT error` when no
# gfx1201 is listed; the older-platform duplicate and the gfx1036 run after it by explicit ordinal, as their own labelled
# columns. Run d (17:17Z, the card by name, every variant built) showed a dependent-chain ratio does NOT survive the
# card's own miner: the alu chain read 226 then 195 G steps/s and the ratios swung from 5.9 to 11.8x to 0.17 to 1.3x
# between runs (the loaded card's scheduler, not the ops), while the Mac and 5090 columns were taken with the card alone.
# Run e: the 9070 XT is switched OFF by the RUNNER (`--cards-off amd:gfx1201` at publish, the app's own card path, put
# back on ANY exit with its own enabled flag, identities and cap: rule of 6 October 2026, a script never posts to
# /api/cards) for its three runs; this script only confirms by the process list that the card's opencl worker is gone;
# the 5090 and the 4070 keep mining (NOT --stop-miners). The gfx1036 and the old-platform columns run
# AFTER the restore, beside the miners, as they are not the card under test. mm8 stays exact=unverified: the gfx12 WMMA
# iu8 16x16x16 fragment layout is in no source at hand, and a guessed CPU layout would turn a wrong guess into exact=no. The probe is the family kit's
# family-probe-cl.exe (proto-opencl/family-probe.c of branch ca3-pc1-amd, cross-compiled with mingw, OpenCL.dll at run
# time; the Mac ran the same source bit-exact on Apple OpenCL), three runs per device, each best of 3 with a fresh seed
# per repetition, device event time, bit-exact against the CPU reference on two whole 32-lane groups. Every family is
# tried through every form AMD's OpenCL C offers; a form that does not compile prints build=failed with the first line
# of the build log and the run goes on (run a's finding: AMD's OpenCL C compiles no amd_perm, no sudot4, no WMMA
# builtin; ds_bpermute does compile). Never quits, pauses, resumes or updates the installed app; never writes
# settings.json. Lines: the probe's own `RESULT FAMILY name= ms= gsteps= ratio= exact= path= variant= ... device= cus=
# platform=` and `RESULT FAMILYBEST ...`, each prefixed `RESULT run=<n> dev=<label>`; a `SUMMARY {json}` line at the end.
# Read back with `node tools/jobs.mjs <job id>`.
$ErrorActionPreference = 'Continue'
$jobName = 'pc1-amd-family'
$kitId = 'fetch-ca3-pc1-amd-family-20261006'
$started = Get-Date
function Stamp { (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') }
function Summary([string] $status, [hashtable] $extra) {
$o = [ordered]@{ job = $jobName; status = $status; duration_s = [int]((Get-Date) - $started).TotalSeconds; finished_at = (Stamp) }
foreach ($k in $extra.Keys) { $o[$k] = $extra[$k] }
'SUMMARY ' + ($o | ConvertTo-Json -Compress -Depth 4)
}
"RESULT start $(Stamp) job=$jobName machine=$env:COMPUTERNAME app_version=$env:IGNEUM_APP_VERSION"
$jobs = Split-Path $env:IGNEUM_JOB_DIR
$kit = Join-Path $jobs $kitId
if (-not (Test-Path $kit)) { "RESULT error kit missing at $kit (the fetch job $kitId runs first; republish it after any app update)"; Summary 'failed' @{ error = 'kit missing' }; exit 2 }
$probe = Join-Path $kit 'bin\family-probe-cl.exe'
$src = Join-Path $kit 'src\family-probe.c'
if (-not (Test-Path $probe)) { "RESULT error probe missing at $probe"; Summary 'failed' @{ error = 'probe missing' }; exit 2 }
"RESULT probe $probe sha256 $((Get-FileHash -Algorithm SHA256 $probe).Hash.ToLower()) bytes $((Get-Item $probe).Length)"
if (Test-Path $src) { "RESULT source family-probe.c sha256 $((Get-FileHash -Algorithm SHA256 $src).Hash.ToLower()) bytes $((Get-Item $src).Length)" }
# what the card carries during the run (read only; nothing is switched)
function Workers { @(Get-CimInstance Win32_Process -Filter "Name = 'igneum-worker-opencl.exe' OR Name = 'igneum-worker-cuda.exe'" -ErrorAction SilentlyContinue | ForEach-Object { "$($_.Name):$($_.ProcessId):[$($_.CommandLine -replace '\s+', ' ')]" }) }
$w = @(Workers)
$amdLoaded = ($w | Where-Object { $_ -match 'igneum-worker-opencl' }).Count -gt 0
$cardState = if ($amdLoaded) { 'loaded' } else { 'quiet' }
"RESULT workers_before $(Stamp) $($w -join ' ')"
"RESULT context card_state=$(if ($amdLoaded) { 'LOADED (an igneum-worker-opencl process mines on an AMD card: absolutes are shared-card figures, ratios stand)' } else { 'quiet (no igneum-worker-opencl process)' })"
# ---- the installed app and the card's settings.json entries (READ ONLY), for the card-alone runs ----
$inst = @("$env:LOCALAPPDATA\Programs\Igneum Miner", "$env:ProgramFiles\Igneum Miner") | Where-Object { Test-Path (Join-Path $_ 'igneum-app.exe') } | Select-Object -First 1
$appDir = if ($env:IGNEUM_APP_DIR) { $env:IGNEUM_APP_DIR } else { Join-Path $env:LOCALAPPDATA 'igneum\app' }
$urlFile = Join-Path $appDir 'app.url'
$base = $null
if (Test-Path $urlFile) { $base = (Get-Content -LiteralPath $urlFile -Raw).Trim().TrimEnd('/') }
"RESULT app install=$inst app_dir=$appDir url_present=$([bool]$base)"
# the 9070 XT's OpenCL device index as the APP numbers it (the installed worker's --list; the probe's own list below
# numbers devices differently), for the process-list check of its worker
$dev = $null
if ($inst -and (Test-Path (Join-Path $inst 'igneum-worker-opencl.exe'))) {
$wl = @(& (Join-Path $inst 'igneum-worker-opencl.exe') --list 2>&1 | ForEach-Object { "$_" })
foreach ($l in $wl) { if ($l -match '^\s*\[(\d+)\].*gfx1201' -and $l -notmatch 'dup') { $dev = [int]$Matches[1]; break } }
}
"RESULT app_device $(if ($null -ne $dev) { $dev } else { 'unknown (no installed worker list: the quiet check falls back to any opencl worker)' })"
# the card is switched off by the RUNNER (`--cards-off amd:gfx1201` at publish), never by this script (rule of 6 October
# 2026, tools/ci/playbook-quit-check.sh rule 2); below only the read-only confirmation that its worker is gone
function CardWorkers {
$procs = @(Get-CimInstance Win32_Process -Filter "Name = 'igneum-worker-opencl.exe'" -ErrorAction SilentlyContinue)
if ($null -ne $dev) { $procs = @($procs | Where-Object { $_.CommandLine -match "--device\s+$dev(\s|$)" }) }
@($procs | ForEach-Object { $_.ProcessId })
}
# the probe's own device list: the 9070 XT by name first (the probe picks the newest platform itself), then the
# older-platform duplicate and the gfx1036 by explicit ordinal as their own columns
$list = @(& $probe --list 2>&1 | ForEach-Object { "$_" })
$list | ForEach-Object { "RESULT list $_" }
$extra = @()
$gfx1201Count = 0; $newest = ''
foreach ($l in $list) {
if ($l -match '^\[(\d+)\] (.*?) \| (.*?) \| driver (\S+)') {
$idx = [int] $Matches[1]; $name = $Matches[2]; $plat = $Matches[3]; $drv = $Matches[4]
if ($name -match 'gfx1201') { $gfx1201Count++; if ($drv -gt $newest) { $newest = $drv } }
if ($name -match 'gfx1201|gfx1036|Radeon' -and $name -notmatch 'NVIDIA') { $extra += [pscustomobject]@{ idx = $idx; name = $name; platform = $plat; driver = $drv } }
}
}
if ($gfx1201Count -eq 0) { "RESULT error no gfx1201 in the probe's list (the eGPU is off the bus: the 9070 XT column stays OWED); listed AMD devices: $(($extra | ForEach-Object { "[$($_.idx)] $($_.name) on $($_.platform) driver $($_.driver)" }) -join ' ; ')"; Summary 'failed' @{ error = 'no gfx1201' }; exit 2 }
# the by-ordinal runs after the by-name one: the gfx1201 entries NOT on the newest driver (the older platform), then the rest
$byOrdinal = @($extra | Where-Object { -not ($_.name -match 'gfx1201' -and $_.driver -eq $newest) })
"RESULT devices by_name=gfx1201 (newest driver $newest, $gfx1201Count gfx1201 entries) then by_ordinal=[$(($byOrdinal | ForEach-Object { "[$($_.idx)] $($_.name) on $($_.platform) driver $($_.driver)" }) -join ' ; ')]"
$runs = 0; $exactRows = 0; $rowsTotal = 0; $built = 0; $failedBuilds = 0; $probeErrors = 0; $mainRows = 0
function RunProbe([string] $label, [string[]] $probeArgs, [int] $r) {
# never name a parameter after the automatic variable for unbound arguments: a splat of it is then empty (run b, 17:10Z)
"RESULT run=$r dev=$label start $(Stamp) args=[$($probeArgs -join ' ')] card_state=$cardState"
$t0 = Get-Date
$lines = @(& $probe @probeArgs --reps 3 2>&1 | ForEach-Object { "$_" })
$rc = $LASTEXITCODE
foreach ($l in $lines) {
if ($l -match '^RESULT ') { "RESULT run=$r dev=$label $($l.Substring(7))" } else { "RESULT run=$r dev=$label text $l" }
if ($l -match '^RESULT FAMILY name=\S+ ms=') { $script:rowsTotal++; if ($l -match ' exact=yes ') { $script:exactRows++ }; if ($label -eq '9070xt') { $script:mainRows++ } }
if ($l -match '^RESULT FAMILY .*build=failed') { $script:failedBuilds++ }
if ($l -match '^RESULT FAMILYBEST name=\S+ ms=') { $script:built++ }
if ($l -match '^RESULT error') { $script:probeErrors++ }
}
"RESULT run=$r dev=$label end $(Stamp) exit=$rc wall_s=$([int]((Get-Date) - $t0).TotalSeconds)"
if ($rc -ne 0) { "RESULT run=$r dev=$label error=probe exit $rc" }
$script:runs++
}
# ---- the 9070 XT alone: off in the app, confirmed quiet, three runs, restored whatever happens ----
$cardAlone = $false
try {
$before = @(CardWorkers)
"RESULT card_workers_before pids=[$($before -join ' ')]"
if ($before.Count -eq 0) { "RESULT card already quiet: no opencl worker for the card (the runner's --cards-off took)"; $cardAlone = $true }
else {
$t = 0
while ($t -lt 150) { Start-Sleep -Seconds 5; $t += 5; if ((@(CardWorkers)).Count -eq 0) { break } }
$left = @(CardWorkers)
if ($left.Count -eq 0) { "RESULT card $(Stamp) quiet after $t s: the card's igneum-worker-opencl process is gone (the card to itself)"; $cardAlone = $true }
else { "RESULT card $(Stamp) UNCONFIRMED after $t s: opencl worker pids [$($left -join ' ')] still run (was the job published with --cards-off amd:gfx1201?); the 9070 XT rows below are LOADED-card figures (run d's class)" }
Start-Sleep -Seconds 8
}
$cardState = if ($cardAlone) { 'alone' } else { 'loaded' }
"RESULT workers_during $(Stamp) $((Workers) -join ' ')"
for ($r = 1; $r -le 3; $r++) { RunProbe '9070xt' @('--device-name', 'gfx1201') $r; Start-Sleep -Seconds 2 }
} finally {
"RESULT runs_9070xt_done $(Stamp) (the card comes back through the RUNNER's restore on any exit, not here)"
}
# ---- the other AMD columns beside the miners (not the card under test) ----
$cardState = if ((@(Get-CimInstance Win32_Process -Filter "Name = 'igneum-worker-opencl.exe'" -ErrorAction SilentlyContinue)).Count -gt 0) { 'loaded' } else { 'quiet' }
foreach ($d in $byOrdinal) {
$label = if ($d.name -match 'gfx1201') { 'gfx1201-old-platform' } elseif ($d.name -match 'gfx1036') { 'gfx1036' } else { 'amd-' + $d.idx }
for ($r = 1; $r -le 3; $r++) { RunProbe $label @('--device', "$($d.idx)") $r; Start-Sleep -Seconds 2 }
}
"RESULT workers_after $(Stamp) $((Workers) -join ' ')"
"RESULT end $(Stamp)"
$status = if ($mainRows -gt 0) { 'done' } elseif ($rowsTotal -gt 0) { 'partial' } else { 'failed' }
Summary $status @{ runs = $runs; family_rows = $rowsTotal; rows_9070xt = $mainRows; card_alone_9070xt = $cardAlone; exact_rows = $exactRows; failed_builds = $failedBuilds; familybest_rows = $built; probe_errors = $probeErrors }
if ($status -eq 'failed') { exit 1 }
exit 0