107 lines
7.1 KiB
PowerShell
107 lines
7.1 KiB
PowerShell
# Igneum run job: the efficiency sweep on PC 1's RTX 5090 (machine ae432dc7), unattended. 4 October 2026.
|
|
# Published as a `run` job with --elevated --stop-miners (docs/plans/miner-eff.md): the installed app stops its
|
|
# miners and holds them, this script starts a SECOND engine from the same install with `--sweep` in a scratch data
|
|
# folder (the real settings.json and machine-id copied in, remote jobs and auto-update switched off there), that
|
|
# engine finds the installed app's node on 127.0.0.1:26610, mines on the 5090 with the live program, steps the cap
|
|
# 100% -> 50% (75 s a step), prints the SWEEP table on stdout, leaves the chosen cap in force and quits. Every SWEEP
|
|
# line is re-emitted as a RESULT line, so `node tools/jobs.mjs <job id>` shows the table. The installed app's
|
|
# miners restart when the job ends. Elevated, so nvidia-smi -pl needs no prompt (the engine detects that: mode=direct).
|
|
# UNTESTED on a PC as of 4 Oct 2026 (parse-checked only).
|
|
$ErrorActionPreference = 'Continue'
|
|
$resultTag = 'SWEEP'
|
|
$budgetMinutes = 40
|
|
$started = Get-Date
|
|
$deadline = $started.AddMinutes($budgetMinutes)
|
|
function Say([string] $m) { Write-Host ("[" + (Get-Date -Format 'HH:mm:ss') + "] " + $m) }
|
|
|
|
# the engine: the per-user install (0.3.3+), else Program Files (0.3.0 to 0.3.2)
|
|
$exe = $null
|
|
foreach ($d in @((Join-Path $env:LOCALAPPDATA 'Programs\Igneum Miner'), (Join-Path $env:ProgramFiles 'Igneum Miner'))) {
|
|
$p = Join-Path $d 'igneum-app.exe'
|
|
if (Test-Path $p) { $exe = $p; break }
|
|
}
|
|
if (-not $exe) { Write-Output 'RESULT SWEEP error=no_engine reason=igneum-app.exe_not_found'; exit 2 }
|
|
$ver = (& $exe --version 2>&1 | Out-String).Trim()
|
|
Say ("engine: " + $exe + " (" + $ver + ")")
|
|
if ($ver -notmatch 'igneum-app (\d+)\.(\d+)\.(\d+)') { Write-Output 'RESULT SWEEP error=version_unknown'; exit 2 }
|
|
# --sweep exists from the build that carries src/sweep.rs; an older engine would just start mining in the browser
|
|
$appDir = $env:IGNEUM_APP_DIR
|
|
if (-not $appDir) { $appDir = Join-Path $env:LOCALAPPDATA 'igneum\app' }
|
|
|
|
# the scratch data root: its own app dir, node dir (unused: the node is external) and logs
|
|
$root = Join-Path $env:LOCALAPPDATA 'igneum-sweep'
|
|
$sApp = Join-Path $root 'app'
|
|
$sLogs = Join-Path $root 'logs'
|
|
New-Item -ItemType Directory -Force -Path $sApp, $sLogs | Out-Null
|
|
foreach ($f in @('settings.json', 'machine-id', 'wallet.json')) {
|
|
$src = Join-Path $appDir $f
|
|
if (Test-Path $src) { Copy-Item -LiteralPath $src -Destination (Join-Path $sApp $f) -Force }
|
|
}
|
|
# the copies are verbatim: the engine switches jobs, updates and proving off itself under --sweep (Settings::for_measurement, 0.3.13)
|
|
if (-not (Test-Path (Join-Path $sApp 'settings.json'))) { Write-Output 'RESULT SWEEP error=no_settings reason=the_installed_app_has_no_settings.json'; exit 2 }
|
|
Remove-Item -LiteralPath (Join-Path $sApp 'app.url') -Force -ErrorAction SilentlyContinue
|
|
|
|
# the cap state before, for the report
|
|
$smi = Join-Path $env:ProgramFiles 'NVIDIA Corporation\NVSMI\nvidia-smi.exe'
|
|
if (-not (Test-Path $smi)) { $smi = Join-Path $env:SystemRoot 'System32\nvidia-smi.exe' }
|
|
if (Test-Path $smi) {
|
|
$q = (& $smi --query-gpu=index,name,power.draw,power.limit,power.default_limit,power.min_limit,power.max_limit --format=csv,noheader 2>&1 | Out-String).Trim()
|
|
Write-Output ("RESULT SWEEP before " + ($q -replace "`r?`n", ' | '))
|
|
}
|
|
|
|
# the sweep engine: status every 10 s (6 rate samples per 60 s hold instead of 2)
|
|
$env:IGNEUM_APP_DATA = $root
|
|
$env:IGNEUM_APP_LOGS = $sLogs
|
|
$env:IGNEUM_APP_STATUS_SECS = '10'
|
|
$env:IGNEUM_APP_NO_OTA = '1' # C35: a second engine never runs the updater (the installer would quit the installed app)
|
|
# C35 (5 October 2026): the engine's output goes to a FILE, never a pipe. A pipe's write end is inherited by every
|
|
# process the engine starts (its miners and workers), so after an abort the installed app's jobs runner waits for an
|
|
# EOF that never comes and hangs in its own quit; and the engine's whole tree is killed at the end (nothing orphaned).
|
|
$outFile = Join-Path $root 'engine-stdout.log'
|
|
$errFile = Join-Path $root 'engine-stderr.log'
|
|
Remove-Item -LiteralPath $outFile, $errFile -Force -ErrorAction SilentlyContinue
|
|
$p = Start-Process -FilePath $exe -ArgumentList '--sweep' -WorkingDirectory (Split-Path $exe) -WindowStyle Hidden -PassThru -RedirectStandardOutput $outFile -RedirectStandardError $errFile
|
|
Say ("engine started, pid " + $p.Id + ", data " + $root + ", stdout " + $outFile)
|
|
function EndTree([int] $procId, [string] $why) {
|
|
$before = @(Get-Process -Name 'igneum-app', 'igneum-miner', 'igneum-worker-cuda', 'igneum-worker-opencl', 'igneum-worker-metal' -ErrorAction SilentlyContinue).Count
|
|
& taskkill /T /F /PID $procId 2>&1 | Out-Null
|
|
Start-Sleep -Seconds 2
|
|
$after = @(Get-Process -Name 'igneum-app', 'igneum-miner', 'igneum-worker-cuda', 'igneum-worker-opencl', 'igneum-worker-metal' -ErrorAction SilentlyContinue).Count
|
|
Write-Output ('RESULT ' + $resultTag + ' tree ended (' + $why + '): igneum processes ' + $before + ' -> ' + $after + ' (the installed app''s own miners are stopped and held by the job)')
|
|
}
|
|
$seen = 0
|
|
$rows = 0
|
|
while (-not $p.HasExited) {
|
|
Start-Sleep -Seconds 5
|
|
$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 '^SWEEP ') { Write-Output ('RESULT ' + $l); if ($l -match '^SWEEP card=') { $rows++ } }
|
|
elseif ($l -match '^(URL|STATE) ') { }
|
|
else { Say $l }
|
|
}
|
|
if ((Get-Date) -gt $deadline) {
|
|
Say ("budget of " + $budgetMinutes + " min spent; asking the sweep engine to quit")
|
|
$u = Join-Path $sApp 'app.url'
|
|
if (Test-Path $u) { try { Invoke-WebRequest -Uri ((Get-Content -LiteralPath $u -Raw).Trim() + 'api/quit') -Method POST -Body '{}' -ContentType 'application/json' -UseBasicParsing -TimeoutSec 5 | Out-Null } catch { } }
|
|
Start-Sleep -Seconds 20
|
|
if (-not $p.HasExited) { EndTree $p.Id 'budget' }
|
|
Write-Output 'RESULT SWEEP error=budget_exceeded'
|
|
}
|
|
}
|
|
$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 '^SWEEP ') { Write-Output ('RESULT ' + $l); if ($l -match '^SWEEP card=') { $rows++ } } }
|
|
Say ("sweep engine exited " + $p.ExitCode + " after " + [int]((Get-Date) - $started).TotalSeconds + " s, " + $rows + " table rows")
|
|
EndTree $p.Id 'end of run'
|
|
if (Test-Path $smi) {
|
|
$q = (& $smi --query-gpu=index,power.draw,power.limit --format=csv,noheader 2>&1 | Out-String).Trim()
|
|
Write-Output ("RESULT SWEEP after " + ($q -replace "`r?`n", ' | '))
|
|
}
|
|
# the sweep engine's own log: the SWEEP lines and what happened around them
|
|
$log = Get-ChildItem -Path $sLogs -Filter 'app-*.log' -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
if ($log) {
|
|
Say ("engine log " + $log.FullName + ":")
|
|
Get-Content -LiteralPath $log.FullName | Where-Object { $_ -match 'SWEEP|sweep|power cap|GPUs:|worker ready|STATUS|exited' } | Select-Object -Last 80 | ForEach-Object { Say (' ' + $_) }
|
|
}
|
|
if ($rows -eq 0) { Write-Output 'RESULT SWEEP error=no_rows'; exit 1 }
|
|
exit 0
|