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

108 lines
8.4 KiB
PowerShell

# Counter ASIC 3.0, PC 1 AMD job 3 (6 October 2026): item 2's per-day item-derivation packs (dr736-genesis and
# dr736-devnet-epoch0, docs/plans/counter-asic-3-derivation.md) on PC 1's RX 9070 XT (machine ae432dc7, gfx1201)
# through the kit's igneum-worker-opencl.exe, with the class v3 control mx8-devnet-epoch0 in the same job. Published
# as a plain signed `run` job (NOT --stop-miners) and run BESIDE THE MINERS: the rows this job is for are build and
# compile times and bit-exactness, which a shared card does not change, plus a 60 s rate whose ratio to the control
# in the same job stands on a shared card (absolutes do not; the process list says what the card carried). Nothing
# is switched; the script never quits, pauses, resumes or updates the installed app and never writes settings.json.
# Per pack, two passes: pass 1 is the cold compile (the first clBuildProgram of that kernel text on this PC today;
# AMD's driver caches compiled kernels on disk, so pass 2 is the cached figure and is printed beside it), the 1 GiB
# daily build (the worker's `cache .. dataset .. ms` line), the self-test (cache FNV, dataset head, 64 samples, 96
# vector lanes) and the 2^24 fingerprint at base nonce 0 against the Mac's (dr736-genesis 50e3eaa779da4f1e,
# dr736-devnet-epoch0 9553f6d5c667205a, mx8-devnet-epoch0 90f794dd556f7a3b) with 60 timed dispatches for the rate;
# pass 2 takes 3 dispatches. The compile time is the worker's own `build <ms> clBuildProgram` line (host.c of branch
# ca3-pc1-amd), the OpenCL equivalent of the CUDA worker's NVRTC line (+1.1 s per dr736 pack on the 5090).
# Lines: `RESULT DERIVE pack=<name> build_ms=<x> build_ms_cached=<x2> dataset_ms=<y> fingerprint=<hex> match=<yes/no>
# mhs=<z> ratio_to_mx8=<r> ...`; a `SUMMARY {json}` line at the end. Read back with `node tools/jobs.mjs <job id>`.
$ErrorActionPreference = 'Continue'
$jobName = 'pc1-amd-derive'
$kitId = 'fetch-ca3-pc1-amd-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)
}
$expected = @{ 'mx8-devnet-epoch0' = '90f794dd556f7a3b'; 'dr736-genesis' = '50e3eaa779da4f1e'; 'dr736-devnet-epoch0' = '9553f6d5c667205a' }
$order = @('mx8-devnet-epoch0', 'dr736-genesis', 'dr736-devnet-epoch0')
"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 }
$exe = Join-Path $kit 'bin\igneum-worker-opencl.exe'
$packs = Join-Path $kit 'packs'
if (-not (Test-Path $exe)) { "RESULT error worker missing at $exe"; Summary 'failed' @{ error = 'worker missing' }; exit 2 }
if (-not (Test-Path $packs)) { "RESULT error packs missing at $packs"; Summary 'failed' @{ error = 'packs missing' }; exit 2 }
"RESULT worker kit $exe sha256 $((Get-FileHash -Algorithm SHA256 $exe).Hash.ToLower()) bytes $((Get-Item $exe).Length)"
foreach ($pk in $order) {
$d = Join-Path $packs $pk
if (-not (Test-Path (Join-Path $d 'kernel_bound.cl'))) { "RESULT error pack $pk missing at $d"; Summary 'failed' @{ error = "pack $pk missing" }; exit 2 }
"RESULT pack $pk kernel_bound.cl sha256 $((Get-FileHash -Algorithm SHA256 (Join-Path $d 'kernel_bound.cl')).Hash.ToLower()) program.json sha256 $((Get-FileHash -Algorithm SHA256 (Join-Path $d 'program.json')).Hash.ToLower())"
}
# the OpenCL device index of the 9070 XT (the installed worker's list when present: the app's own indices)
$inst = @("$env:LOCALAPPDATA\Programs\Igneum Miner", "$env:ProgramFiles\Igneum Miner") | Where-Object { Test-Path (Join-Path $_ 'igneum-app.exe') } | Select-Object -First 1
$listExe = $exe
if ($inst -and (Test-Path (Join-Path $inst 'igneum-worker-opencl.exe'))) { $listExe = Join-Path $inst 'igneum-worker-opencl.exe' }
$list = @(& $listExe --list 2>&1 | ForEach-Object { "$_" })
$list | ForEach-Object { "RESULT list $_" }
$dev = $null
foreach ($l in $list) { if ($l -match '^\s*\[(\d+)\].*gfx1201' -and $l -notmatch 'dup') { $dev = [int]$Matches[1]; break } }
if ($null -eq $dev) { "RESULT error no gfx1201 device in --list (the eGPU is off the bus: every row OWED)"; Summary 'failed' @{ error = 'no gfx1201' }; exit 2 }
"RESULT device $dev gfx1201 (list from $listExe)"
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)
$loaded = ($w | Where-Object { $_ -match "igneum-worker-opencl.*--device\s+$dev(\s|$)" }).Count -gt 0
"RESULT workers_before $(Stamp) $($w -join ' ')"
"RESULT context card_state=$(if ($loaded) { 'LOADED (the card mines beside this job: build, compile and bit-exact rows stand, the rate is a ratio to the control only)' } else { 'quiet (no opencl worker with --device ' + $dev + ')' })"
function RunPack([string] $pk, [int] $batches, [string] $tag) {
$d = Join-Path $packs $pk
$t0 = Get-Date
"RESULT bench $tag start $(Stamp) batches=$batches"
$lines = @(& $exe --bench-pack --pack $d --batches $batches --batch-log2 24 --device $dev 2>&1 | ForEach-Object { "$_" })
$rc = $LASTEXITCODE
$lines | ForEach-Object { "RESULT bench $tag $_" }
"RESULT bench $tag end $(Stamp) exit=$rc wall_s=$([int]((Get-Date) - $t0).TotalSeconds)"
$o = [ordered]@{ pack = $pk; rc = $rc; build_ms = ''; cache_ms = ''; dataset_ms = ''; check_ms = ''; all_ms = ''; check = ''; fp = ''; mhs = ''; error = '' }
foreach ($l in $lines) {
if ($l -match '^build ([\d.]+) ms clBuildProgram') { $o.build_ms = $Matches[1] }
if ($l -match '^pack .*: cache (\d+) dataset (\d+) hot \d+ check (\d+) ms \((\d+) ms in all\)') { $o.cache_ms = $Matches[1]; $o.dataset_ms = $Matches[2]; $o.check_ms = $Matches[3]; $o.all_ms = $Matches[4] }
if ($l -match '^RESULT pack=') { if ($l -match 'fingerprint=([0-9a-f]{16})') { $o.fp = $Matches[1] }; if ($l -match 'mhs=([\d.]+)') { $o.mhs = $Matches[1] }; if ($l -match 'check=(\S+)') { $o.check = $Matches[1] } }
}
if (-not $o.fp -or $rc -ne 0) { $e = ($lines | Where-Object { $_ -match 'FAIL|error|MISMATCH' } | Select-Object -First 1); if (-not $e) { $e = "exit $rc, no RESULT line" }; $o.error = ($e -replace '\s+', ' ') }
return $o
}
$rows = @{}
$ok = 0
foreach ($pk in $order) {
$p1 = RunPack $pk 60 "$pk#1"
Start-Sleep -Seconds 2
$p2 = RunPack $pk 3 "$pk#2"
$rows[$pk] = @{ p1 = $p1; p2 = $p2 }
if ($p1.error) { "RESULT DERIVE pack=$pk error=$($p1.error)" } else { $ok++ }
Start-Sleep -Seconds 2
}
# the rows: build (cold and cached), dataset, fingerprint, rate and its ratio to the control measured in the same job
$ctrl = $rows['mx8-devnet-epoch0'].p1
foreach ($pk in $order) {
$p1 = $rows[$pk].p1; $p2 = $rows[$pk].p2
if ($p1.error) { continue }
$want = $expected[$pk]
$match = if ($p1.fp -eq $want) { 'yes' } else { 'no' }
$match2 = if ($p2.fp -eq $want) { 'yes' } else { 'no' }
$ratio = ''
if ($ctrl -and -not $ctrl.error -and $ctrl.mhs -and $p1.mhs -and [double] $ctrl.mhs -gt 0) { $ratio = [math]::Round([double] $p1.mhs / [double] $ctrl.mhs, 3) }
$buildDelta = ''
if ($ctrl -and -not $ctrl.error -and $ctrl.build_ms -and $p1.build_ms) { $buildDelta = [math]::Round([double] $p1.build_ms - [double] $ctrl.build_ms, 1) }
"RESULT DERIVE pack=$pk build_ms=$($p1.build_ms) build_ms_cached=$($p2.build_ms) build_ms_over_mx8=$buildDelta dataset_ms=$($p1.dataset_ms) dataset_ms_pass2=$($p2.dataset_ms) cache_ms=$($p1.cache_ms) check_ms=$($p1.check_ms) fingerprint=$($p1.fp) match=$match fingerprint_pass2=$($p2.fp) match_pass2=$match2 check=$($p1.check) mhs=$($p1.mhs) ratio_to_mx8=$ratio card_state=$(if ($loaded) { 'loaded' } else { 'quiet' }) card=gfx1201 harness=opencl-kit expected=$want"
}
"RESULT workers_after $(Stamp) $((Workers) -join ' ')"
"RESULT end $(Stamp)"
$status = if ($ok -eq $order.Count) { 'done' } elseif ($ok -gt 0) { 'partial' } else { 'failed' }
Summary $status @{ packs_ok = $ok; packs_wanted = $order.Count; device = $dev; card_state = $(if ($loaded) { 'loaded' } else { 'quiet' }) }
if ($status -eq 'failed') { exit 1 }
exit 0