Windows package 0.3.0: prebuilt one-click workers first, nvcc/cl.exe build path as the fallback
igneum-common.ps1 uses igneum-worker-cuda.exe (with nvrtc64_*_0.dll next to it) and igneum-worker-opencl.exe when they are in the folder, passes the exported pack with --pack, and only surveys the toolchain (Find-Toolchain) when a worker is missing or FORCE_BUILD=1; the dashboard and the status block name the path per card; a prebuilt worker that is not ready after 150 s falls back to the build path once when a toolchain exists; 90 s of seed mismatch errors re-export the pack and restart the vendor; WORKER_ARCH overrides the NVRTC target. make-package.sh ships the two exes, the two NVRTC DLLs, the licence texts, THIRD-PARTY.md and TEST.md (what the first RTX 5090 run should print and what to send back). README.txt, the bats, proto-cuda/README.md (nvrtc/ section), WINDOWS-MINER.md and the bench log updated with what the Mac measured. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e43e8e0d86
commit
f375ec0d94
9 changed files with 313 additions and 40 deletions
|
|
@ -601,7 +601,7 @@ BIOS already had SVM on.
|
|||
|
||||
## 4 October 2026, devnet v4 cut-over: generator v2, 2/3 floor, three nodes and a seed on a fresh chain
|
||||
|
||||
Sequence (BST): seed re-staged from `6457ca95` (build 55 min on the 2-vCPU VM, 08:55 to 09:54); node 1 stopped and the v3
|
||||
Sequence (local time, UTC+1): seed re-staged from `6457ca95` (build 55 min on the 2-vCPU VM, 08:55 to 09:54); node 1 stopped and the v3
|
||||
database moved aside at 10:05:30, `igneumd` v4 up at 10:05:31 with the execution layer; observer peer and `observer.mjs`
|
||||
restarted on fresh appdirs at 10:06:10; seed switched with `switch-v4.sh` at 10:06:28 and synced at 10:07:38 (`blocks=2`,
|
||||
`peers=1`); Mac Metal miner (generator v2 port, `prepare 1`) first accepted block at 10:07:35; the PC joined at 10:10:55
|
||||
|
|
@ -611,3 +611,22 @@ block 0 with 9 identities after five minutes. First NVIDIA card to mine a genera
|
|||
Mac share. One launcher defect found only on Windows: `"$machine:$vendorName"` in `igneum-common.ps1` is a drive-qualified
|
||||
variable to PowerShell, so the file failed to parse (fixed, braces). The first finality lock is due at DAA 7,200, two hours
|
||||
after the v4 genesis; the first hourly swap at DAA 3,600.
|
||||
|
||||
## 4 October 2026, one-click Windows workers: what the Mac could measure (no NVIDIA GPU here)
|
||||
|
||||
Package 0.3.0 replaces the build-on-the-PC workers with two prebuilt exes (`proto-cuda/nvrtc/worker.cpp`: driver API +
|
||||
NVRTC loaded at run time; `proto-opencl/host.c --pack`: OpenCL.dll loaded at run time, pack read at run time). Both
|
||||
cross-compile with Homebrew mingw-w64 16.2 and import only KERNEL32 and the Universal CRT (1,117,184 and 78,336 bytes
|
||||
stripped). The NVRTC DLLs (12.8.93) add 93 MB to the zip. Checks run on the M5 Max, same protocol script for both
|
||||
(`proto-cuda/nvrtc/emu/serve-check.sh`: jobs on pack A, a background prepare of a second pack, the swap, a job after
|
||||
the swap, 15 to 17 found hashes against `igneum-pow hash-bound`):
|
||||
|
||||
| Worker | How it ran here | First pack (cache / dataset / self-test) | Prepare of pack B (reported) | Verdict |
|
||||
|---|---|---|---|---|
|
||||
| igneum-worker-cuda (emulation backend: pack kernels on host threads, NVRTC stand-in) | `nvrtc/emu/test.sh` | 157 / 4,758 / 1,702 ms | 8,413 ms (cache 132, dataset 4,759, check 1,671) | PASS, 17 of 17 sampled hashes, source check PASS for 4 files |
|
||||
| igneum-bench-cl --pack (Apple OpenCL 1.2, built against a different placeholder pack) | `proto-opencl/test-generic.sh` | 53 / 289 / 1,588 ms | 2,083 ms (build 212, cache 25, dataset 197, check 1,387) | PASS, 15 of 15 sampled hashes |
|
||||
|
||||
The self-test times are dominated by reading the 256 MiB cache back and hashing it on one CPU thread (FNV-1a 64 over
|
||||
2^26 words); the emulation's dataset build is 256 host threads over 2^24 items and says nothing about a GPU. Nothing
|
||||
NVIDIA was measured: the first NVRTC compile, cubin load and hash rate on the RTX 5090 are owed from the PC run
|
||||
(`proto-cuda/windows-app/TEST.md` lists the lines to copy here).
|
||||
|
|
|
|||
|
|
@ -21,6 +21,40 @@ the first 5090 run on a version 2 pack is still owed (`docs/bench-log.md`, 4 Oct
|
|||
carries `IGNEUM_GENERATOR 2`, `IGNEUM_PROGRAM_ATTEMPT` and `IGNEUM_PROGRAM_ID`; a worker built from a version 1 pack
|
||||
cannot serve a version 2 node.
|
||||
|
||||
## The one-click worker (nvrtc/, 4 October 2026)
|
||||
|
||||
`nvrtc/worker.cpp` is the worker the Windows package ships as `igneum-worker-cuda.exe`: nothing to install but the
|
||||
NVIDIA driver. It opens `nvcuda.dll` (the driver API, in every driver) and `nvrtc64_120_0.dll` (NVIDIA's runtime
|
||||
compiler, redistributable, shipped next to the exe with `nvrtc-builtins64_128.dll`; `nvrtc/THIRD-PARTY.md`) with
|
||||
`LoadLibrary`/`GetProcAddress` (`nvrtc/cuda_api.h`), reads a pack directory at run time (`nvrtc/packfile.h`: program.h,
|
||||
seeds.txt, vectors.h), hands NVRTC the pack's `kernel.cu` and `kernel_bound.cu` up to the host launch wrappers with
|
||||
`program.h` and `memhard.h` as named headers, byte for byte, loads the cubin through the driver, fills the cache, builds
|
||||
the dataset and self-tests both plus the three vector warps against `vectors.h` before it serves a job. It speaks the
|
||||
same `--serve` protocol as `host.cu` (jobs, `prepare` in the background for the hourly swap, `found`/`done`); a job on
|
||||
seeds it has no pair for makes it look for the miner's pack by `seeds.txt` and build it in the foreground. `host.cu`
|
||||
stays the ahead-of-time harness and the launcher's fallback when the prebuilt worker is missing and a toolkit exists.
|
||||
|
||||
```
|
||||
nvrtc/
|
||||
worker.cpp the worker (C++17, driver API + NVRTC loaded at run time, cross-compiled with mingw)
|
||||
cuda_api.h the function-pointer table for the two libraries
|
||||
packfile.h C99 reader for a pack directory: sizes, seeds, vectors; the self-test verdict (shared with proto-opencl/host.c --pack)
|
||||
fetch-redist.sh downloads and verifies cuda.h, nvrtc.h, the two NVRTC DLLs and the Khronos OpenCL headers into nvrtc/redist/ (gitignored)
|
||||
build-windows.sh cross-compiles igneum-worker-cuda.exe and proto-opencl/igneum-worker-opencl.exe (static, KERNEL32 + Universal CRT only)
|
||||
THIRD-PARTY.md every third-party file, its URL, version, SHA-256 and licence clause
|
||||
emu/ the Mac check: emu_backend.cpp (driver API and NVRTC as host functions, the pack's kernels on host threads,
|
||||
the NVRTC source compared byte for byte with the pack), test.sh, serve-check.sh (shared with proto-opencl/test-generic.sh)
|
||||
```
|
||||
|
||||
What was proven on the Mac (4 October 2026): `emu/test.sh` builds the worker against two real packs (the devnet epoch
|
||||
0 pack and a second epoch and day exported by `igneum-pow`), runs `--check` (self-test PASS, 96 of 96 lanes) and a
|
||||
`--serve` session: 64 + 64 + 32 found on pack A including the nonces either side of the 32-bit boundary, pack B
|
||||
prepared in the background with its self-test PASS, the swap, the self-heal rebuild of pack A, 17 sampled hashes equal
|
||||
to `igneum-pow hash-bound`, and the NVRTC source check PASS for all four files (kernel.cu 7,385 of 8,893 bytes with
|
||||
the 1,508-byte host wrapper tail dropped, kernel_bound.cu 6,003 of 6,887, program.h and memhard.h identical). The exe
|
||||
cross-compiles and links with mingw. Not proven here: that the real NVRTC accepts the text with the two stub headers
|
||||
and that the driver runs the cubin; that is the RTX 5090 run (`windows-app/TEST.md`).
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
|
|
@ -40,6 +74,7 @@ proto-cuda/
|
|||
memhard.h memory-hard packs only: the cache fill and item derivation core, compiled for device and host
|
||||
memhard.metal memory-hard packs only: the Metal cache-fill and build kernels the Mac ran
|
||||
emu/ CPU emulation shim: compile and check a pack with plain clang++/g++, no GPU
|
||||
nvrtc/ the one-click worker (driver API + NVRTC at run time), its Mac emulation and the third-party record
|
||||
```
|
||||
|
||||
Four packs are checked in, all generator version 2 with 128 loads per hash. `igneum-genesis` and `igneum-hourly` use the
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
# Mining the Igneum devnet from a Windows PC
|
||||
|
||||
Package 0.3.0 (4 October 2026) ships prebuilt workers: `igneum-worker-cuda.exe` (driver API + NVRTC, compiles each
|
||||
hourly program on the card) and `igneum-worker-opencl.exe`; nothing to install but the driver, no CUDA Toolkit, no Visual
|
||||
Studio. The build path below (nvcc, cl.exe) is now the fallback for a missing worker or `FORCE_BUILD=1`. See
|
||||
`windows-app/README.txt`, `windows-app/TEST.md` and `README.md` (the nvrtc/ section). The rest of this page is the
|
||||
3 October 2026 build-on-the-PC design and stays valid for that path.
|
||||
|
||||
Written 3 October 2026 for the project lead's PC (RTX 5090 at about 229 MH/s on the memory-hard hash, Ryzen 9800X3D with the
|
||||
gfx1036 integrated AMD GPU at about 4 MH/s; `docs/bench-log.md`). Two ways: the packaged test (one double-click), or by
|
||||
hand from this repository. Both mine against node 1 on the Mac (LAN 192.168.68.64, gRPC 26610, p2p 26611), which runs
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
Igneum devnet v4 for Windows (package 0.2.0, 4 October 2026): the node and the miners in one window. Extract the whole zip to a fresh short path such as C:\igneum-v4 first (a new folder, not over the old package).
|
||||
Devnet v4 is a new chain from genesis. The node keeps its database in a fresh folder, %LOCALAPPDATA%\igneum\devnet-v4; the old chain's folder (%LOCALAPPDATA%\igneum\devnet) is not touched and can be deleted later. Every node and miner on the network moved to v4 together; an old igneumd.exe or igneum-miner.exe cannot follow this chain.
|
||||
1. START-IGNEUM.bat. It starts igneumd (RPC 127.0.0.1:26610, p2p 0.0.0.0:26611, peered to the seed node 188.245.5.161:26611 and the Mac 192.168.68.64:26611), waits until the node is synced, then finds the GPUs, builds the CUDA and OpenCL workers on the first run (CUDA Toolkit 12.8 or newer plus Visual Studio with the MSVC v143 x64 component) and starts ONE miner per GPU vendor with MINERS=8 identities inside it (one worker owns the card; each identity has its own vote key and payout label). Settings are at the top of the bat.
|
||||
Igneum devnet v4 for Windows (package 0.3.0, 4 October 2026): the node and the miners in one window. Nothing to install but the graphics driver. Extract the whole zip to a fresh short path such as C:\igneum-v4 (a new folder, not over an old package), then double-click START-IGNEUM.bat.
|
||||
What is new in 0.3.0: the GPU workers come prebuilt. igneum-worker-cuda.exe drives an NVIDIA card through the driver (nvcuda.dll) and compiles each hourly lottery program on the card itself with NVIDIA's runtime compiler, which ships next to it (nvrtc64_120_0.dll and nvrtc-builtins64_128.dll, see THIRD-PARTY.md); igneum-worker-opencl.exe drives an AMD (or any OpenCL) card and lets the driver's own compiler build the program. No CUDA Toolkit, no Visual Studio, no SDK. The old build path (proto-cuda\build.bat with nvcc, proto-opencl\build.bat with cl.exe) is still in the package and is used only when a prebuilt worker is missing from the folder or FORCE_BUILD=1 is set at the top of the bat; the dashboard says which path each card runs on.
|
||||
Devnet v4 is a new chain from genesis. The node keeps its database in %LOCALAPPDATA%\igneum\devnet-v4; the old chain's folder (%LOCALAPPDATA%\igneum\devnet) is not touched and can be deleted. Every node and miner on the network moved to v4 together; an old igneumd.exe or igneum-miner.exe cannot follow this chain.
|
||||
1. START-IGNEUM.bat. It starts igneumd (RPC 127.0.0.1:26610, p2p 0.0.0.0:26611, peered to the seed node 188.245.5.161:26611 and the Mac 192.168.68.64:26611), waits until the node is synced, finds the GPUs, exports the current hourly program from the node (a "pack", proto-cuda\packs\devnet) and starts ONE miner per GPU vendor with MINERS=8 identities inside it (one worker owns the card; each identity has its own vote key and payout label). The worker reads the pack, compiles it on the card, builds the 256 MiB cache and the 1 GiB dataset, checks them and the program against the pack's expected values (a self-test printed in the miner log) and then says ready. On the RTX 5090 that takes a few seconds. Settings are at the top of the bat.
|
||||
Firewall: the first time, Windows Defender Firewall asks about igneumd.exe. Tick Private networks and click Allow access (that lets the other nodes dial this PC). If you clicked Cancel, run ALLOW-FIREWALL.bat once.
|
||||
2. The window is a dashboard, redrawn every 2 s, with the version in the header: the NODE card first (state in colour: starting, syncing, synced, restarting, stopped; blocks, headers, blue score, peers, the chain's blocks per second, the difficulty direction, the node's uptime), then one card per GPU (hash rate in big digits, blocks found, identities, one cell per miner process), the network share line, the last events (node started, synced in N s, peer joined or left, node restarted, blocks found, worker ready, the next hourly program compiled, hourly program rebuilt, miner restarted, upload failed) and a footer. Set PLAIN=1 at the top of the bat for a scrolling log instead; the launcher uses it by itself when the window is not a real console.
|
||||
2. The window is a dashboard, redrawn every 2 s, with the version in the header: the NODE card first (state in colour: starting, syncing, synced, restarting, stopped; blocks, headers, blue score, peers, the chain's blocks per second, the difficulty direction, the node's uptime), then one card per GPU (hash rate in big digits, blocks found, identities, which worker path the card runs on: "prebuilt worker, NVRTC compiles on the card (driver only)", "prebuilt worker, the OpenCL driver compiles (driver only)" or "worker built here with ..."), the network share line, the last events (node started, synced in N s, peer joined or left, node restarted, blocks found, worker ready, the next hourly program compiled, miner restarted, upload failed) and a footer. Set PLAIN=1 at the top of the bat for a scrolling log instead; the launcher uses it by itself when the window is not a real console.
|
||||
3. Ctrl+C in the window stops the miners first, then the node, then uploads the logs one last time; the window stays open with a summary. If the window was closed instead, STOP-IGNEUM.bat stops everything cleanly.
|
||||
Payout: block rewards go to an EVM address. PAYOUT_EVM at the top of the bat sets one for the whole PC; left empty, the launcher derives one address per GPU vendor from this PC's name (the same on every run; it is printed in the launcher log and the status block). Finality voting is on: every identity signs every checkpoint (VOTE=0 switches it off).
|
||||
The hourly program change: every hour the lottery program changes. The v4 worker compiles the next program in the background as soon as the node announces it (about 10 minutes before the boundary) and swaps at the boundary with no pause ("hot swap"; the dashboard says "the next hourly program is compiled"). If nvcc is not on the PATH the worker cannot do that, and the miner exits with code 42 at the boundary instead: the launcher re-exports the pack, rebuilds the worker and restarts the miner, as before.
|
||||
The hourly program change: every hour the lottery program changes. About ten minutes before the boundary the node announces the next program; the miner writes its pack (proto-cuda\packs\prepare\<epoch>-<day>) and tells the worker, which compiles it on the card in the background, builds its cache and dataset, self-tests it and keeps it ready; at the boundary the worker swaps with no pause (the dashboard says "the next hourly program is compiled and resident"). If that ever fails, the CUDA worker finds the pack by itself when the first job on the new program arrives and compiles it then (a pause of a few seconds); and if a worker keeps erroring on the new seeds for 90 s, the launcher re-exports the pack and restarts that card's miner. --exit-on-seed-change stays on as the last fallback: a worker that cannot prepare at all exits with code 42 at the boundary and the launcher restarts it on a fresh pack.
|
||||
If a prebuilt worker never reports ready (150 s), the launcher says so in the events; when a CUDA Toolkit and Visual Studio happen to be installed it builds a worker from source with them instead, otherwise look at the miner log named in the event (the worker prints the reason: a missing DLL, a compile error, a driver too old for CUDA 12).
|
||||
A node crash is restarted after a random 5 to 60 s; the miners are restarted once the node is back and synced (their connection dies with the node). The PC is held awake while the window runs; for the night also set Sleep to Never in Settings > System > Power.
|
||||
Logs land next to the bat (igneum-<stamp>.log for the launcher, node-<stamp>.log for the node, nvidia-<stamp>.log and amd-<stamp>.log per miner process) and are uploaded every 60 s with upload-log.bat under the labels igneum-<PC>, nodelog-<PC>, nvidia-<PC>, amd-<PC>.
|
||||
Logs land next to the bat (igneum-<stamp>.log for the launcher, node-<stamp>.log for the node, nvidia-<stamp>.log and amd-<stamp>.log per miner process; the worker's ready, info and self-test lines are in the miner log) and are uploaded every 60 s with upload-log.bat under the labels igneum-<PC>, nodelog-<PC>, nvidia-<PC>, amd-<PC>.
|
||||
Separate entry points, same code (igneum-common.ps1): START-NODE.bat runs the node alone (its card and events), START-MINING.bat runs the miners alone against a node that is already up (NODE_HOST=auto picks 127.0.0.1 when one runs here, else the Mac).
|
||||
The node also serves the execution layer's Ethereum JSON-RPC on 127.0.0.1:26790 (chain id 4463); --evm-disable in EXTRA_ARGS turns it off.
|
||||
If the node exits at once with a database error, delete %LOCALAPPDATA%\igneum\devnet-v4 and start again; it resyncs from the seed node and the Mac in seconds.
|
||||
Files: START-IGNEUM.bat, START-NODE.bat, START-MINING.bat, STOP-IGNEUM.bat, ALLOW-FIREWALL.bat and their .ps1 files, igneum-common.ps1, igneumd.exe with libstdc++-6.dll, libgcc_s_seh-1.dll and libwinpthread-1.dll (keep them next to it), igneum-miner.exe, upload-log.bat, proto-cuda\ and proto-opencl\ (the worker sources and build.bat).
|
||||
TEST.md says what to look for on the first run of this package (the lines the dashboard and the miner log should show) and what to send back.
|
||||
Files: START-IGNEUM.bat, START-NODE.bat, START-MINING.bat, STOP-IGNEUM.bat, ALLOW-FIREWALL.bat and their .ps1 files, igneum-common.ps1, igneumd.exe with libstdc++-6.dll, libgcc_s_seh-1.dll and libwinpthread-1.dll (keep them next to it), igneum-miner.exe, igneum-worker-cuda.exe with nvrtc64_120_0.dll and nvrtc-builtins64_128.dll (keep them next to it), igneum-worker-opencl.exe, LICENSE-NVIDIA-CUDA-EULA.txt, LICENSE-Khronos-OpenCL-Headers.txt, THIRD-PARTY.md, TEST.md, upload-log.bat, proto-cuda\ and proto-opencl\ (the worker sources and build.bat, for the build path only).
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
@echo off
|
||||
rem Igneum for Windows, devnet v4 (package 0.2.0): the node and the miners in one window. Double-click this file.
|
||||
rem Igneum for Windows, devnet v4 (package 0.3.0): the node and the miners in one window. Double-click this file.
|
||||
rem It starts igneumd (your own node, peered to the seed node and the Mac), waits until it is synced, then finds the GPUs
|
||||
rem in this PC, builds the matching GPU workers on first run (NVIDIA: CUDA, AMD: OpenCL) and runs one igneum-miner per
|
||||
rem in this PC, starts the prebuilt GPU workers (NVIDIA: igneum-worker-cuda.exe, which compiles each hourly program on the
|
||||
rem card with NVRTC; AMD: igneum-worker-opencl.exe; nothing to install but the driver) and runs one igneum-miner per
|
||||
rem worker against the node on this PC, with MINERS identities inside that one miner. The window shows a dashboard: the
|
||||
rem NODE card first, then one card per GPU, the last events. Logs land next to this file and are uploaded every 60
|
||||
rem seconds. Stop with Ctrl+C (miners first, then the node); the window stays open at the end. If the window was closed
|
||||
|
|
@ -37,9 +38,15 @@ rem Devnet UTXO payout address (igneumdev:...). Leave empty for one address per
|
|||
set "PAYOUT_ADDRESS="
|
||||
rem Finality voting: 1 = every identity signs every checkpoint (the default on v4). 0 = mine without voting.
|
||||
set "VOTE=1"
|
||||
rem NVIDIA: CUDA device index (0 = first card) and the nvcc architecture (sm_120 = RTX 50 series; "native" lets nvcc pick).
|
||||
rem NVIDIA: CUDA device index (0 = first card). CUDA_ARCH is the nvcc architecture for the build path only (sm_120 = RTX 50
|
||||
rem series; "native" lets nvcc pick); the prebuilt worker finds the card's own architecture by itself. WORKER_ARCH overrides
|
||||
rem the prebuilt worker's NVRTC target (sm_XY or compute_XY); leave it empty.
|
||||
set "NVIDIA_DEVICE=0"
|
||||
set "CUDA_ARCH=sm_120"
|
||||
set "WORKER_ARCH="
|
||||
rem 1 = ignore the prebuilt workers and build the old ones from source with nvcc / cl.exe (needs CUDA Toolkit + Visual
|
||||
rem Studio); for a comparison run only.
|
||||
set "FORCE_BUILD=0"
|
||||
rem AMD: by default the first OpenCL GPU whose vendor string contains AMD_VENDOR is used, never an NVIDIA device.
|
||||
rem Set AMD_DEVICE to a flat device index from the worker's --list output to override.
|
||||
set "AMD_VENDOR=Advanced Micro Devices"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
@echo off
|
||||
rem Igneum devnet v4 mining for Windows (package 0.2.0), the miners only. Double-click this file.
|
||||
rem Igneum devnet v4 mining for Windows (package 0.3.0), the miners only. Double-click this file.
|
||||
rem It finds the GPUs in this PC, builds the matching GPU workers on first run (NVIDIA: CUDA, AMD: OpenCL), and runs
|
||||
rem one igneum-miner per worker (MINERS identities inside it) against a node that is already running (START-NODE.bat
|
||||
rem here, or the Mac). Logs land next to this file and are uploaded every 60 seconds. START-IGNEUM.bat runs the node
|
||||
|
|
@ -17,9 +17,15 @@ rem Devnet UTXO payout address (igneumdev:...). Leave empty for one address per
|
|||
set "PAYOUT_ADDRESS="
|
||||
rem Finality voting: 1 = every identity signs every checkpoint (the default on v4). 0 = mine without voting.
|
||||
set "VOTE=1"
|
||||
rem NVIDIA: CUDA device index (0 = first card) and the nvcc architecture (sm_120 = RTX 50 series; "native" lets nvcc pick).
|
||||
rem NVIDIA: CUDA device index (0 = first card). CUDA_ARCH is the nvcc architecture for the build path only (sm_120 = RTX 50
|
||||
rem series; "native" lets nvcc pick); the prebuilt worker finds the card's own architecture by itself. WORKER_ARCH overrides
|
||||
rem the prebuilt worker's NVRTC target (sm_XY or compute_XY); leave it empty.
|
||||
set "NVIDIA_DEVICE=0"
|
||||
set "CUDA_ARCH=sm_120"
|
||||
set "WORKER_ARCH="
|
||||
rem 1 = ignore the prebuilt workers and build the old ones from source with nvcc / cl.exe (needs CUDA Toolkit + Visual
|
||||
rem Studio); for a comparison run only.
|
||||
set "FORCE_BUILD=0"
|
||||
rem AMD: by default the first OpenCL GPU whose vendor string contains AMD_VENDOR is used, never an NVIDIA device.
|
||||
rem Set AMD_DEVICE to a flat device index from the worker's --list output to override.
|
||||
set "AMD_VENDOR=Advanced Micro Devices"
|
||||
|
|
|
|||
86
proto-cuda/windows-app/TEST.md
Normal file
86
proto-cuda/windows-app/TEST.md
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# First run of package 0.3.0 (prebuilt workers): what to look for
|
||||
|
||||
Written 4 October 2026 on the Mac, where the workers could only be checked without an NVIDIA GPU (the CUDA worker's
|
||||
host logic through a CPU emulation of the driver API and NVRTC, the OpenCL worker through Apple's OpenCL runtime).
|
||||
The real NVRTC compile and the real driver run happen for the first time on the RTX 5090 PC. This page says what a
|
||||
good run prints and what to send back if it does not.
|
||||
|
||||
## Before you start
|
||||
|
||||
Extract the zip to a fresh short folder (C:\igneum-v4). Nothing to install. These files must sit together in it:
|
||||
`igneum-worker-cuda.exe`, `nvrtc64_120_0.dll`, `nvrtc-builtins64_128.dll`, `igneum-worker-opencl.exe`,
|
||||
`igneum-miner.exe`, `igneumd.exe`. The NVIDIA driver must be the one that already mines (617.14 on 4 October 2026
|
||||
is fine; the driver API needs a driver for CUDA 12.x).
|
||||
|
||||
## What the dashboard should show
|
||||
|
||||
1. In the launcher log (igneum-<stamp>.log) right after "GPUs found": `prebuilt workers: igneum-worker-cuda.exe with
|
||||
nvrtc64_120_0.dll, igneum-worker-opencl.exe` and `workers to start: nvidia (prebuilt worker, NVRTC compiles on the
|
||||
card (driver only)), amd (prebuilt worker, the OpenCL driver compiles (driver only))`. No "tools:" line: nothing is
|
||||
looked for when the prebuilt workers are there.
|
||||
2. After the node is synced: the phase line `starting the prebuilt RTX 5090 worker`, then the card appears with
|
||||
`prebuilt worker, NVRTC compiles on the card (driver only)` next to its name.
|
||||
3. Within about 10 s the event `RTX 5090 worker ready (prebuilt worker, NVRTC compiles on the card (driver only)),
|
||||
hot swap at the hour boundary`. The AMD card the same with "the OpenCL driver compiles".
|
||||
4. Then `mining` in green and a hash rate about the one the nvcc-built worker gave (229 MH/s on the 5090 with 8
|
||||
identities on 3 October 2026; the kernel text is the same, only the compiler changed, so a large gap either way
|
||||
is worth a note).
|
||||
5. About ten minutes before the hour boundary: `RTX 5090: the next hourly program is compiled and resident (hot swap
|
||||
ready)`. At the boundary no pause, no restart event; the miner log says `switched to the prepared pair`.
|
||||
|
||||
## What the miner log should show (nvidia-<stamp>.log)
|
||||
|
||||
The worker's own lines, in this order:
|
||||
|
||||
```
|
||||
worker: info igneum-worker-cuda 1.0 (4 October 2026): device 0 NVIDIA_GeForce_RTX_5090 (sm_120, 170 SMs), driver 12.x from nvcuda.dll, NVRTC 12.8 from C:\igneum-v4\nvrtc64_120_0.dll, target sm_120 (the device's architecture, listed by NVRTC)
|
||||
worker: ready cuda NVIDIA_GeForce_RTX_5090 pack igneum-epoch/<64 hex>/day/<hex> dataset-log2 28 batch 4194304 regs <N> prepare 1 path nvrtc 12.8 driver 12.x arch sm_120 worker 1.0 (4 October 2026) (prepare support: yes, hot swap at the boundary)
|
||||
worker: info first pack proto-cuda\packs\devnet: nvrtc <ms> cache <ms> dataset <ms> check <ms> ms; self-test PASS (cache head, last line and FNV-1a 64 <16 hex>; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes)
|
||||
```
|
||||
|
||||
The self-test is the proof that NVRTC compiled the same program nvcc did: the 96 vector lanes are the outputs the
|
||||
Rust CPU interpreter put in the pack, and the cache FNV covers all 2^26 words of the cache. `regs` should be close to
|
||||
what the nvcc build reported for the same program. Every `found` is still re-checked by the miner's CPU code
|
||||
(`WORKER MISMATCH` in the log would be the alarm; expect none).
|
||||
|
||||
At the hourly prepare:
|
||||
|
||||
```
|
||||
PREPARE sent for epoch seed ... (N DAA blocks before the boundary ...)
|
||||
worker: info prepare started for epoch <16 hex> day <hex> from C:\igneum-v4\proto-cuda\packs\prepare\<epoch>-<day> (NVRTC sm_120 in the background)
|
||||
worker: prepared <epoch hex> <day hex> <ms> nvrtc <ms> cache <ms> dataset <ms> check <ms> ms; self-test PASS (...) resident 2 programs 2 datasets
|
||||
```
|
||||
|
||||
For the AMD worker (amd-<stamp>.log): `ready opencl <device> platform AMD_Accelerated_Parallel_Processing pack ...
|
||||
prepare 1 path prebuilt-generic`, then `info first pack ..\proto-cuda\packs\devnet: cache <ms> dataset <ms> check <ms>
|
||||
ms (...); self-test PASS (...)`.
|
||||
|
||||
## Timings worth writing down (none measured yet on NVIDIA)
|
||||
|
||||
From the `info first pack` and `prepared` lines: the NVRTC compile time (`nvrtc <ms>`, expected a few seconds for the
|
||||
two files), the cache fill, the dataset build and the self-test time (the self-test reads 256 MiB back over PCIe and
|
||||
hashes it on the CPU, so a few hundred ms). These go into docs/bench-log.md with the date and the driver version.
|
||||
|
||||
## If it fails
|
||||
|
||||
- `error 0 nvrtc64_120_0.dll (and nvrtc-builtins64_128.dll) must sit next to ...`: the zip was not extracted whole.
|
||||
- `error 0 the CUDA driver library (nvcuda.dll) is not installed` or `the driver library lacks ...`: NVIDIA driver
|
||||
missing or too old. Update the driver.
|
||||
- `error 0 nvrtcCompileProgram kernel.cu for sm_120: NVRTC_ERROR_COMPILATION: <log>`: the compiler rejected the pack's
|
||||
text. The log is on that line (the first 600 characters). Send the whole miner log: this is the one thing the Mac
|
||||
could not try, and the fix is in the stub headers the worker hands NVRTC (proto-cuda/nvrtc/worker.cpp,
|
||||
STUB_CUDA_RUNTIME and STUB_CSTDINT).
|
||||
- `error 0 pack ...: self-test FAIL (...)`: the compiled program ran but gave other numbers than the CPU reference.
|
||||
Send the miner log; the line says which check failed and the first differing lane.
|
||||
- `error 0 cuModuleLoadData kernel.cu (sm_120): ...`: the driver refused the cubin (driver older than the NVRTC
|
||||
target). The prebuilt worker picks the card's own architecture by itself (CUDA_ARCH is for the nvcc path only);
|
||||
`WORKER_ARCH=compute_90` at the top of the bat makes it emit PTX for the driver to compile instead. Send the log.
|
||||
- The dashboard's `the prebuilt RTX 5090 worker is not ready after 150 s`: with CUDA Toolkit and Visual Studio still
|
||||
installed on this PC the launcher then builds the old worker with nvcc and mining continues on it (the card line
|
||||
changes to "worker built here with nvcc + MSVC"); the miner log of the first attempt holds the reason.
|
||||
- `FORCE_BUILD=1` at the top of the bat forces the old nvcc / cl.exe path for a comparison run.
|
||||
|
||||
## What to send back
|
||||
|
||||
The launcher log, the two miner logs (they are uploaded every minute as well) and, for the bench log, the three
|
||||
timing lines above plus `nvidia-smi`'s driver version.
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
# start-mining.ps1 (miners only) and start-node.ps1 (node only), so the logic lives once. 3 October 2026.
|
||||
# Devnet v4, package 0.2.0 (4 October 2026): peers list (seed node and Mac), fresh appdir devnet-v4, one miner process
|
||||
# with --identities per card, EVM payout address, finality voting on, hot swap through the worker's prepare command.
|
||||
# Package 0.3.0 (4 October 2026): prebuilt one-click workers (igneum-worker-cuda.exe with NVRTC, igneum-worker-opencl.exe),
|
||||
# nothing to install but the GPU driver; the nvcc / cl.exe build path stays as the fallback when a worker is missing.
|
||||
# The caller sets $launcherName ('igneum', 'launcher' or 'node-launcher') before dot-sourcing; it names the launcher log.
|
||||
#
|
||||
# Sections: settings, logging and events, the node (igneumd), the chain reader (igneum-miner watch), GPUs and tools,
|
||||
|
|
@ -21,7 +23,7 @@ $ErrorActionPreference = 'Continue'
|
|||
$root = $PSScriptRoot
|
||||
Set-Location $root
|
||||
if (-not $launcherName) { $launcherName = 'launcher' }
|
||||
$packageVersion = '0.2.0'
|
||||
$packageVersion = '0.3.0'
|
||||
$chainVersion = 'devnet v4'
|
||||
|
||||
# ---- settings (environment variables set by the bat; defaults match the bats) ---------------------------------------------
|
||||
|
|
@ -56,6 +58,7 @@ $payoutEvm = $env:PAYOUT_EVM # 0x + 40 hex; empty = one address per ven
|
|||
$vote = ($env:VOTE -ne '0') # finality voting is on unless VOTE=0
|
||||
$nvidiaDevice = Get-Setting 'NVIDIA_DEVICE' '0'
|
||||
$cudaArch = Get-Setting 'CUDA_ARCH' 'sm_120'
|
||||
$workerArch = $env:WORKER_ARCH # prebuilt CUDA worker only: NVRTC target (sm_XY or compute_XY); empty = the card's own architecture
|
||||
$amdVendor = Get-Setting 'AMD_VENDOR' 'Advanced Micro Devices'
|
||||
$amdDevice = $env:AMD_DEVICE
|
||||
$useNvidia = ($env:USE_NVIDIA -ne '0')
|
||||
|
|
@ -83,6 +86,17 @@ $packDir = Join-Path $root 'proto-cuda\packs\devnet'
|
|||
# Where the v4 miner writes the pack of the NEXT program (--prepare-packs): the worker compiles it in the background and
|
||||
# swaps at the epoch boundary with no exit (hot swap). One folder per epoch and day under here.
|
||||
$preparePackDir = Join-Path $root 'proto-cuda\packs\prepare'
|
||||
# The one-click workers (package 0.3.0, 4 October 2026): prebuilt exes next to igneum-miner.exe that need nothing but
|
||||
# the GPU driver. igneum-worker-cuda.exe compiles each hourly program on the card itself with NVRTC (nvrtc64_*_0.dll
|
||||
# and nvrtc-builtins64_*.dll next to it, NVIDIA's redistributable); igneum-worker-opencl.exe builds it through the
|
||||
# OpenCL driver's own compiler. When a prebuilt worker is missing (or FORCE_BUILD=1), the nvcc / cl.exe build path of
|
||||
# proto-cuda\build.bat and proto-opencl\build.bat is used as before, which needs CUDA Toolkit + Visual Studio.
|
||||
$prebuiltCuda = Join-Path $root 'igneum-worker-cuda.exe'
|
||||
$prebuiltCl = Join-Path $root 'igneum-worker-opencl.exe'
|
||||
$packDirRel = 'proto-cuda\packs\devnet' # $packDir relative to $root, for the prebuilt worker's --pack (worker-args split on spaces)
|
||||
$script:workerPath = @{} # per vendor: 'prebuilt' or 'build'
|
||||
$script:tools = $null # the toolchain survey (Find-Toolchain), made only when the build path is needed
|
||||
$script:lastSeeds = $null # the seeds of the last exported pack (Build-Worker's cache key)
|
||||
$started = Get-Date
|
||||
$gpuNames = @()
|
||||
$vendors = @{} # $vendors[name] = @{ name; card; exe; instances; rebuilds; building; evm }
|
||||
|
|
@ -496,14 +510,10 @@ function Set-LibFallback {
|
|||
return [bool](Get-Command cl.exe -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
# Lists the GPUs and the tools, logs which workers will start. Returns the vendor plan (@('nvidia', 'amd'), or empty).
|
||||
function Find-Hardware {
|
||||
$script:gpuNames = @()
|
||||
try { $script:gpuNames = @(Get-CimInstance Win32_VideoController | ForEach-Object { $_.Name }) } catch { Log "could not list GPUs through WMI: $_" }
|
||||
Log ("GPUs found: " + ($(if ($gpuNames.Count) { $gpuNames -join '; ' } else { 'none reported' })))
|
||||
$hasNvidia = ($gpuNames | Where-Object { $_ -match 'NVIDIA' }).Count -gt 0
|
||||
$hasAmd = ($gpuNames | Where-Object { $_ -match 'AMD|Radeon' }).Count -gt 0
|
||||
|
||||
# The toolchain survey for the build path (MSVC environment, nvcc, an OpenCL SDK). Made once, only when a worker has to
|
||||
# be built here: with the prebuilt workers present nothing is looked for. Returns @{ cl; nvcc; openclSdk }.
|
||||
function Find-Toolchain {
|
||||
if ($script:tools) { return $script:tools }
|
||||
$haveCl = Import-VcVars
|
||||
if (-not $haveCl) { $haveCl = Set-LibFallback }
|
||||
if ($haveCl) {
|
||||
|
|
@ -519,21 +529,59 @@ function Find-Hardware {
|
|||
if ($env:OPENCL_SDK -and (Test-Path (Join-Path $env:OPENCL_SDK 'include\CL\cl.h'))) { $openclSdk = $env:OPENCL_SDK }
|
||||
elseif ($env:CUDA_PATH -and (Test-Path (Join-Path $env:CUDA_PATH 'include\CL\cl.h'))) { $openclSdk = $env:CUDA_PATH }
|
||||
elseif ($env:OCL_ROOT -and (Test-Path (Join-Path $env:OCL_ROOT 'include\CL\cl.h'))) { $openclSdk = $env:OCL_ROOT }
|
||||
|
||||
Log ("tools: nvcc " + $(if ($haveNvcc) { 'found' } else { 'MISSING (install CUDA Toolkit 12.8 or newer)' }) +
|
||||
", MSVC $vcvarsVer " + $(if ($haveCl) { 'found' } else { "MISSING (install Visual Studio with the MSVC v143 x64 component; looked at $vcvars)" }) +
|
||||
", OpenCL SDK " + $(if ($openclSdk) { "found at $openclSdk" } else { 'MISSING (the CUDA Toolkit ships one, or set OPENCL_SDK)' }))
|
||||
$script:tools = @{ cl = $haveCl; nvcc = $haveNvcc; openclSdk = $openclSdk }
|
||||
return $script:tools
|
||||
}
|
||||
|
||||
function Test-CanBuild([string]$name) {
|
||||
$t = Find-Toolchain
|
||||
if ($name -eq 'nvidia') { return ($t.nvcc -and $t.cl) }
|
||||
return ($t.cl -and [bool]$t.openclSdk)
|
||||
}
|
||||
|
||||
# What the dashboard and the log say about a vendor's worker
|
||||
function Get-PathText([string]$name) {
|
||||
if ($script:workerPath[$name] -eq 'prebuilt') {
|
||||
if ($name -eq 'nvidia') { return 'prebuilt worker, NVRTC compiles on the card (driver only)' }
|
||||
return 'prebuilt worker, the OpenCL driver compiles (driver only)'
|
||||
}
|
||||
if ($name -eq 'nvidia') { return 'worker built here with nvcc + MSVC' }
|
||||
return 'worker built here with cl.exe + an OpenCL SDK'
|
||||
}
|
||||
|
||||
# Lists the GPUs, chooses the prebuilt worker per vendor (or the build path when it is missing and a toolchain exists),
|
||||
# logs which workers will start. Returns the vendor plan (@('nvidia', 'amd'), or empty).
|
||||
function Find-Hardware {
|
||||
$script:gpuNames = @()
|
||||
try { $script:gpuNames = @(Get-CimInstance Win32_VideoController | ForEach-Object { $_.Name }) } catch { Log "could not list GPUs through WMI: $_" }
|
||||
Log ("GPUs found: " + ($(if ($gpuNames.Count) { $gpuNames -join '; ' } else { 'none reported' })))
|
||||
$hasNvidia = ($gpuNames | Where-Object { $_ -match 'NVIDIA' }).Count -gt 0
|
||||
$hasAmd = ($gpuNames | Where-Object { $_ -match 'AMD|Radeon' }).Count -gt 0
|
||||
$forceBuild = ($env:FORCE_BUILD -eq '1')
|
||||
|
||||
$nvrtcDlls = @(Get-ChildItem -Path $root -Filter 'nvrtc64_*_0.dll' -ErrorAction SilentlyContinue | Where-Object { $_.Name -notmatch '\.alt\.' })
|
||||
$havePrebuiltCuda = (Test-Path $prebuiltCuda) -and ($nvrtcDlls.Count -gt 0)
|
||||
$havePrebuiltCl = Test-Path $prebuiltCl
|
||||
if ((Test-Path $prebuiltCuda) -and -not $havePrebuiltCuda) { Log 'igneum-worker-cuda.exe is here but no nvrtc64_*_0.dll is next to it: the prebuilt CUDA worker cannot run (extract the whole zip)' }
|
||||
Log ("prebuilt workers: " + $(if ($havePrebuiltCuda) { "igneum-worker-cuda.exe with $($nvrtcDlls[0].Name)" } else { 'no CUDA worker' }) + ", " + $(if ($havePrebuiltCl) { 'igneum-worker-opencl.exe' } else { 'no OpenCL worker' }) + $(if ($forceBuild) { ' (FORCE_BUILD=1: not used)' } else { '' }))
|
||||
|
||||
$plan = @()
|
||||
$skipped = @()
|
||||
if ($hasNvidia -and $useNvidia) {
|
||||
if ($haveNvcc -and $haveCl) { $plan += 'nvidia' } else { $skipped += "nvidia: GPU present but " + $(if (-not $haveNvcc) { 'nvcc' } else { 'MSVC' }) + " is missing" }
|
||||
if ($havePrebuiltCuda -and -not $forceBuild) { $plan += 'nvidia'; $script:workerPath['nvidia'] = 'prebuilt' }
|
||||
elseif (Test-CanBuild 'nvidia') { $plan += 'nvidia'; $script:workerPath['nvidia'] = 'build' }
|
||||
else { $skipped += "nvidia: GPU present, no prebuilt igneum-worker-cuda.exe (with nvrtc64_*_0.dll) in this folder, and " + $(if (-not $script:tools.nvcc) { 'nvcc' } else { 'MSVC' }) + " is missing for the build path" }
|
||||
} elseif ($hasNvidia) { $skipped += 'nvidia: disabled by USE_NVIDIA=0' } else { $skipped += 'nvidia: no NVIDIA GPU reported' }
|
||||
if ($hasAmd -and $useAmd) {
|
||||
if ($haveCl -and $openclSdk) { $plan += 'amd' } else { $skipped += "amd: GPU present but " + $(if (-not $haveCl) { 'MSVC' } else { 'an OpenCL SDK' }) + " is missing" }
|
||||
if ($havePrebuiltCl -and -not $forceBuild) { $plan += 'amd'; $script:workerPath['amd'] = 'prebuilt' }
|
||||
elseif (Test-CanBuild 'amd') { $plan += 'amd'; $script:workerPath['amd'] = 'build' }
|
||||
else { $skipped += "amd: GPU present, no prebuilt igneum-worker-opencl.exe in this folder, and " + $(if (-not $script:tools.cl) { 'MSVC' } else { 'an OpenCL SDK' }) + " is missing for the build path" }
|
||||
} elseif ($hasAmd) { $skipped += 'amd: disabled by USE_AMD=0' } else { $skipped += 'amd: no AMD GPU reported' }
|
||||
|
||||
Log ("workers to start: " + $(if ($plan.Count) { $plan -join ', ' } else { 'none' }))
|
||||
Log ("workers to start: " + $(if ($plan.Count) { ($plan | ForEach-Object { "$_ ($(Get-PathText $_))" }) -join ', ' } else { 'none' }))
|
||||
foreach ($s in $skipped) { Log "skipped $s" }
|
||||
return ,$plan
|
||||
}
|
||||
|
|
@ -571,6 +619,11 @@ function Export-Pack {
|
|||
}
|
||||
|
||||
function Build-Worker([string]$name, [string]$seeds) {
|
||||
if ($script:workerPath[$name] -eq 'prebuilt') {
|
||||
$exe = if ($name -eq 'nvidia') { $prebuiltCuda } else { $prebuiltCl }
|
||||
Log "$name worker: prebuilt $exe serves the pack in $packDir (nothing to build; it compiles the program on the card)"
|
||||
return $exe
|
||||
}
|
||||
if ($name -eq 'nvidia') { $exe = Join-Path $root 'proto-cuda\igneum-bench-cuda-devnet.exe'; $dir = Join-Path $root 'proto-cuda'; $cmd = "build.bat devnet $cudaArch" }
|
||||
else { $exe = Join-Path $root 'proto-opencl\igneum-bench-cl-devnet.exe'; $dir = Join-Path $root 'proto-opencl'; $cmd = 'build.bat devnet' }
|
||||
$stampFile = "$exe.seeds"
|
||||
|
|
@ -602,8 +655,9 @@ function Initialize-Vendors($plan) {
|
|||
New-Item -ItemType Directory -Force -Path $preparePackDir | Out-Null
|
||||
$seeds = Export-Pack
|
||||
if (-not $seeds) { return $false }
|
||||
$script:lastSeeds = $seeds
|
||||
foreach ($name in $plan) {
|
||||
$script:phase = "building the $(Get-CardName $name) worker (about 30 s for CUDA)"
|
||||
$script:phase = if ($script:workerPath[$name] -eq 'prebuilt') { "starting the prebuilt $(Get-CardName $name) worker" } else { "building the $(Get-CardName $name) worker (about 30 s for CUDA)" }
|
||||
Draw-Dashboard
|
||||
$exe = Build-Worker $name $seeds
|
||||
if (-not $exe) { Log "$name skipped: no worker binary"; continue }
|
||||
|
|
@ -618,9 +672,11 @@ function Initialize-Vendors($plan) {
|
|||
runId = "$name-$machine$suffix-$stamp"; proc = $null; restarts = 0; starts = 0; startedAt = $null; restartAt = $null; exitCode = $null;
|
||||
logPos = [long]0; logRem = ''; errPos = [long]0; errRem = ''; accepted = 0; found = (New-Object System.Collections.ArrayList);
|
||||
status = $null; ready = $false; readyAt = $null; lastLineAt = $null; errors = 0; lastError = ''; lastErrorAt = $null; rejected = 0; lastNoNodeAt = $null;
|
||||
identities = $identitiesPerProc; prepare = $null }
|
||||
identities = $identitiesPerProc; prepare = $null; mismatchSince = $null; lastMismatchAt = $null }
|
||||
}
|
||||
$script:vendors[$name] = @{ name = $name; card = (Get-CardName $name); exe = $exe; instances = $instances; rebuilds = 0; building = $false; evm = (Get-EvmAddress $name) }
|
||||
$script:vendors[$name] = @{ name = $name; card = (Get-CardName $name); exe = $exe; instances = $instances; rebuilds = 0; building = $false; evm = (Get-EvmAddress $name);
|
||||
path = $script:workerPath[$name]; pathText = (Get-PathText $name); fellBack = $false }
|
||||
Log "$name: $(Get-PathText $name)"
|
||||
}
|
||||
$script:phase = ''
|
||||
if ($vendors.Count -eq 0) { Log 'no worker could be built; see the launcher log'; return $false }
|
||||
|
|
@ -653,13 +709,18 @@ function Start-Miner($v, $inst) {
|
|||
if ($inst.identities -gt 1) { $margs += @('--identities', [string]$inst.identities) }
|
||||
if (-not $vote) { $margs += '--no-vote' }
|
||||
if ($payout) { $margs += @('--address', $payout) } else { $margs += @('--payout-label', $inst.label) }
|
||||
# The prebuilt workers take the exported pack with --pack (a relative path: the miner splits worker-args on spaces,
|
||||
# cwd is $root for nvidia and proto-opencl for amd); the workers built here have it compiled in.
|
||||
if ($v.name -eq 'nvidia') {
|
||||
if ($nvidiaJobNonces) { $margs += @('--job-nonces', $nvidiaJobNonces) }
|
||||
$margs += @('--worker-args', ('"--device ' + $nvidiaDevice + '"'))
|
||||
$wargs = '--device ' + $nvidiaDevice
|
||||
if ($v.path -eq 'prebuilt') { $wargs += ' --pack ' + $packDirRel; if ($workerArch) { $wargs += ' --arch ' + $workerArch } }
|
||||
$margs += @('--worker-args', ('"' + $wargs + '"'))
|
||||
} else {
|
||||
if ($amdJobNonces) { $margs += @('--job-nonces', $amdJobNonces) }
|
||||
if ($amdDevice) { $margs += @('--worker-args', ('"--device ' + $amdDevice + '"')) }
|
||||
else { $margs += @('--worker-args', ('"--vendor ' + $amdVendor.Replace(' ', '_') + '"')) }
|
||||
$wargs = if ($amdDevice) { '--device ' + $amdDevice } else { '--vendor ' + $amdVendor.Replace(' ', '_') }
|
||||
if ($v.path -eq 'prebuilt') { $wargs += ' --pack ..\' + $packDirRel }
|
||||
$margs += @('--worker-args', ('"' + $wargs + '"'))
|
||||
}
|
||||
Set-Content -Path $inst.log -Value "igneum-mine-test $($inst.label) $machine $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') node $nodeUrl run $($inst.runId) start $($inst.starts)"
|
||||
$inst.proc = Start-Process -FilePath $miner -ArgumentList $margs -WorkingDirectory $(if ($v.name -eq 'amd') { Join-Path $root 'proto-opencl' } else { $root }) -RedirectStandardOutput $inst.log -RedirectStandardError $inst.err -NoNewWindow -PassThru
|
||||
|
|
@ -758,7 +819,7 @@ function Update-Instance($v, $inst) {
|
|||
# v4 hot swap: "prepare 1" on the ready line means the worker compiles the next program itself and swaps at
|
||||
# the boundary with no exit; "prepare 0" (no nvcc on PATH) means the old exit-42 rebuild path.
|
||||
if ($l -match ' prepare 1') { $inst.prepare = $true } elseif ($l -match ' prepare 0') { $inst.prepare = $false }
|
||||
if ($inst.starts -eq 1) { Add-Event ("$($v.card) worker ready" + $(if ($inst.prepare -eq $true) { ', hot swap at the hour boundary' } elseif ($inst.prepare -eq $false) { ', no hot swap (nvcc missing): rebuild at the boundary' } else { '' })) 'ok' }
|
||||
if ($inst.starts -eq 1) { Add-Event ("$($v.card) worker ready ($($v.pathText))" + $(if ($inst.prepare -eq $true) { ', hot swap at the hour boundary' } elseif ($inst.prepare -eq $false) { ', no hot swap (nvcc missing): rebuild at the boundary' } else { '' })) 'ok' }
|
||||
} elseif ($l -match ' worker: prepared ') {
|
||||
Add-Event "$($v.card): the next hourly program is compiled and resident (hot swap ready)" 'build'
|
||||
} elseif ($l -match ' worker: prepare-failed ') {
|
||||
|
|
@ -766,12 +827,19 @@ function Update-Instance($v, $inst) {
|
|||
}
|
||||
}
|
||||
foreach ($l in (Read-NewLines $inst 'err')) {
|
||||
if ($l -match 'seed mismatch') {
|
||||
# The worker has no program for the job's seeds (a prepare failed, or the boundary passed without one): Update-Miners
|
||||
# re-exports the pack and restarts the vendor when this goes on for 90 s
|
||||
if (-not $inst.mismatchSince) { $inst.mismatchSince = Get-Date }
|
||||
$inst.lastMismatchAt = Get-Date
|
||||
}
|
||||
if ($l -match ' rejected nonce=') { $inst.rejected += 1 }
|
||||
elseif ($l -match '^template error') { $inst.lastNoNodeAt = Get-Date }
|
||||
elseif ($l -match 'submit error|template error|WORKER MISMATCH|worker error|worker exited|could not prepare|above target|panicked|CUDA error|FAIL') {
|
||||
$inst.errors += 1; $inst.lastError = $l; $inst.lastErrorAt = Get-Date
|
||||
}
|
||||
}
|
||||
if ($inst.lastMismatchAt -and ((Get-Date) - $inst.lastMismatchAt).TotalSeconds -gt 60) { $inst.mismatchSince = $null; $inst.lastMismatchAt = $null }
|
||||
# keep one hour of found times (the dashboard needs 10 minutes and the share window)
|
||||
$cut = (Get-UnixNow) - 3600
|
||||
while ($inst.found.Count -gt 0 -and [double]$inst.found[0] -lt $cut) { $inst.found.RemoveAt(0) }
|
||||
|
|
@ -802,16 +870,42 @@ function Update-Miners {
|
|||
return
|
||||
}
|
||||
foreach ($v in @($vendors.Values)) {
|
||||
# A prebuilt worker that never reports ready (a DLL missing, an NVRTC or driver error in the miner log): once, after
|
||||
# 150 s, fall back to the build path when a toolchain is installed, else say so and leave it to the miner's restarts
|
||||
if ($v.path -eq 'prebuilt' -and -not $v.fellBack) {
|
||||
$first = $v.instances[0]
|
||||
if ($first.startedAt -and -not $first.ready -and ((Get-Date) - $first.startedAt).TotalSeconds -gt 150) {
|
||||
$v.fellBack = $true
|
||||
if ((Test-CanBuild $v.name) -and $script:lastSeeds) {
|
||||
Add-Event "the prebuilt $($v.card) worker is not ready after 150 s (see $(Split-Path -Leaf $first.log)); building one with the installed toolchain instead" 'error'
|
||||
$script:workerPath[$v.name] = 'build'; $v.path = 'build'; $v.pathText = (Get-PathText $v.name)
|
||||
$v.building = $true
|
||||
Draw-Dashboard
|
||||
Stop-Vendor $v
|
||||
$exe = Build-Worker $v.name $script:lastSeeds
|
||||
if ($exe) { $v.exe = $exe; Add-Event "$($v.card) worker built here, restarting its miners" 'build' } else { Add-Event "the build also failed (see the launcher log); restarting with the prebuilt worker" 'error' }
|
||||
foreach ($inst in $v.instances) { Update-Instance $v $inst; Start-Miner $v $inst; Start-Sleep -Milliseconds 500 }
|
||||
$v.building = $false
|
||||
continue
|
||||
} else {
|
||||
Add-Event "the prebuilt $($v.card) worker is not ready after 150 s: see $(Split-Path -Leaf $first.log); no toolchain here to build one" 'error'
|
||||
}
|
||||
}
|
||||
}
|
||||
$seedChange = $false
|
||||
$why = 'the epoch or day seed changed (miner exit 42)'
|
||||
foreach ($inst in $v.instances) {
|
||||
if ($inst.proc -and $inst.proc.HasExited -and (Get-ExitCode $inst) -eq 42) { $seedChange = $true }
|
||||
if ($inst.mismatchSince -and ((Get-Date) - $inst.mismatchSince).TotalSeconds -gt 90 -and $inst.lastMismatchAt -and ((Get-Date) - $inst.lastMismatchAt).TotalSeconds -lt 45) {
|
||||
$seedChange = $true; $why = 'the worker has had no program for the jobs'' seeds for 90 s (seed mismatch errors)'
|
||||
}
|
||||
}
|
||||
if ($seedChange) {
|
||||
# The whole vendor group restarts: the worker exe cannot be rebuilt while another identity still runs it
|
||||
$v.rebuilds += 1
|
||||
$v.building = $true
|
||||
Log "$($v.name): the epoch or day seed changed (miner exit 42). Stopping its $($v.instances.Count) identities, re-exporting the pack, rebuilding the worker."
|
||||
Add-Event "the hourly program changed, rebuilding the $($v.card) worker" 'build'
|
||||
Log "$($v.name): $why. Stopping its $($v.instances.Count) identities, re-exporting the pack, $(if ($v.path -eq 'prebuilt') { 'restarting the prebuilt worker on it' } else { 'rebuilding the worker' })."
|
||||
Add-Event $(if ($v.path -eq 'prebuilt') { "the hourly program changed, restarting the $($v.card) worker on it" } else { "the hourly program changed, rebuilding the $($v.card) worker" }) 'build'
|
||||
Draw-Dashboard # the build blocks this loop; show the state first
|
||||
Stop-Vendor $v
|
||||
foreach ($inst in $v.instances) { Update-Instance $v $inst } # the last lines of the old log segments
|
||||
|
|
@ -819,12 +913,13 @@ function Update-Miners {
|
|||
$exe = $null
|
||||
$seeds = Export-Pack
|
||||
if ($seeds) {
|
||||
$script:lastSeeds = $seeds
|
||||
$exe = Build-Worker $v.name $seeds
|
||||
if ($exe) { $v.exe = $exe }
|
||||
}
|
||||
$took = ((Get-Date) - $t).TotalSeconds
|
||||
Log ("{0}: rebuild for the new seeds took {1:N1} s in total" -f $v.name, $took)
|
||||
if ($seeds -and $exe) { Add-Event ("the new hourly program is built (took {0:N0} s), {1} {2} miners restarting" -f $took, $v.instances.Count, $v.card) 'build' }
|
||||
if ($seeds -and $exe) { Add-Event ($(if ($v.path -eq 'prebuilt') { "the new hourly program is exported (took {0:N0} s), {1} {2} miners restarting" } else { "the new hourly program is built (took {0:N0} s), {1} {2} miners restarting" }) -f $took, $v.instances.Count, $v.card) 'build' }
|
||||
else { Add-Event ("the rebuild for {0} failed, restarting its miners with the old worker (see the launcher log)" -f $v.card) 'error' }
|
||||
foreach ($inst in $v.instances) { Start-Miner $v $inst; Start-Sleep -Milliseconds 500 }
|
||||
$v.building = $false
|
||||
|
|
@ -907,7 +1002,7 @@ function Print-Status {
|
|||
Log ("{0}: accepted {1}, no STATUS line yet ({2}), restarts {3}, {4}" -f $inst.label, $inst.accepted, $since, $inst.restarts, $st.text)
|
||||
}
|
||||
}
|
||||
Log ("{0} TOTAL ({1}): {2} identities in {8} process(es), accepted {3} blocks ({4} in the last 10 min), {5:N2} MH/s, rebuilds {6}, up {7}, EVM payout {9}" -f $v.name, $v.card, (Get-VendorIdentities $v), $acc, $last10, $total, $v.rebuilds, $up, $v.instances.Count, $v.evm)
|
||||
Log ("{0} TOTAL ({1}): {2} identities in {8} process(es), accepted {3} blocks ({4} in the last 10 min), {5:N2} MH/s, rebuilds {6}, up {7}, EVM payout {9}, {10}" -f $v.name, $v.card, (Get-VendorIdentities $v), $acc, $last10, $total, $v.rebuilds, $up, $v.instances.Count, $v.evm, $v.pathText)
|
||||
}
|
||||
$cs = Get-ChainStats
|
||||
if ($cs) {
|
||||
|
|
@ -1061,6 +1156,7 @@ function Build-Frame {
|
|||
Add-Seg $L (' ' + $v.card) 'White'
|
||||
$ids = Get-VendorIdentities $v
|
||||
if ($v.instances.Count -eq 1 -and $ids -gt 1) { Add-Seg $L " $ids identities, one worker" 'DarkGray' }
|
||||
Add-Seg $L (' ' + $v.pathText) 'DarkGray'
|
||||
if ($v.building) { Add-Seg $L " building the new hourly program$dots" 'Yellow' }
|
||||
elseif ($reported -lt $v.instances.Count -and $reported -gt 0) { Add-Seg $L " $reported of $($v.instances.Count) miners reporting" 'DarkGray' }
|
||||
elseif ($reported -eq 0) { Add-Seg $L ' no report from the miners yet (the first job has to finish)' 'Yellow' }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,10 @@
|
|||
# Builds igneum-windows-v4.zip (the node and the miners in one window on a Windows PC) on the Mac.
|
||||
# Contents: the launchers and igneum-common.ps1 from this directory, upload-log.bat, the firewall scripts, igneumd.exe
|
||||
# with its three mingw runtime DLLs, igneum-miner.exe (the one that prints blue= and synced= in `watch`, needed for the
|
||||
# sync wait), and the worker sources from proto-cuda/ and proto-opencl/. No src.zip: the node exe ships prebuilt.
|
||||
# sync wait), the two prebuilt one-click workers (package 0.3.0, 4 October 2026: igneum-worker-cuda.exe with NVIDIA's
|
||||
# redistributable nvrtc64_120_0.dll and nvrtc-builtins64_128.dll, igneum-worker-opencl.exe; built by
|
||||
# proto-cuda/nvrtc/build-windows.sh after fetch-redist.sh; THIRD-PARTY.md and the two licence texts go with them),
|
||||
# TEST.md, and the worker sources from proto-cuda/ and proto-opencl/ for the build path. No src.zip: the node exe ships prebuilt.
|
||||
# Default exes (4 Oct 2026, devnet v4): the devnet-v4 cross-build in vendor/igneum-node/target-integration/
|
||||
# x86_64-pc-windows-gnu/release/ (built from vendor/igneum-node-v4 at dc749905 by proto-cuda/windows-node/cross-build.sh
|
||||
# with CARGO_TARGET_DIR=target-integration). IGNEUM_WIN_RELEASE points at another release directory.
|
||||
|
|
@ -15,6 +18,13 @@ REL="${IGNEUM_WIN_RELEASE:-$ROOT/vendor/igneum-node/target-integration/x86_64-pc
|
|||
NODE_EXE="${IGNEUMD_EXE:-$REL/igneumd.exe}"
|
||||
MINER_EXE="${IGNEUM_MINER_EXE:-$REL/igneum-miner.exe}"
|
||||
DLL_DIR="${IGNEUM_DLL_DIR:-}" # a directory holding the three DLLs; empty = the Homebrew mingw toolchain
|
||||
NVRTC_DIR="$ROOT/proto-cuda/nvrtc"
|
||||
CUDA_WORKER="$NVRTC_DIR/igneum-worker-cuda.exe"
|
||||
CL_WORKER="$ROOT/proto-opencl/igneum-worker-opencl.exe"
|
||||
[ -f "$CUDA_WORKER" ] && [ -f "$CL_WORKER" ] || { echo "no prebuilt workers; run $NVRTC_DIR/fetch-redist.sh then $NVRTC_DIR/build-windows.sh" >&2; exit 1; }
|
||||
for f in bin/nvrtc64_120_0.dll bin/nvrtc-builtins64_128.dll LICENSE-NVIDIA-CUDA-EULA.txt LICENSE-Khronos-OpenCL-Headers.txt; do
|
||||
[ -f "$NVRTC_DIR/redist/$f" ] || { echo "no $NVRTC_DIR/redist/$f; run $NVRTC_DIR/fetch-redist.sh" >&2; exit 1; }
|
||||
done
|
||||
[ -f "$NODE_EXE" ] || { echo "no $NODE_EXE; cross-compile the node first or set IGNEUMD_EXE" >&2; exit 1; }
|
||||
[ -f "$MINER_EXE" ] || { echo "no $MINER_EXE; cross-compile the miner first or set IGNEUM_MINER_EXE" >&2; exit 1; }
|
||||
# no grep -q here: pipefail would turn the early exit into a miss (strings gets SIGPIPE)
|
||||
|
|
@ -24,9 +34,14 @@ STAGE="$(mktemp -d)/igneum-windows"
|
|||
mkdir -p "$STAGE/proto-cuda/packs" "$STAGE/proto-opencl"
|
||||
cp "$HERE/START-IGNEUM.bat" "$HERE/start-igneum.ps1" "$HERE/START-NODE.bat" "$HERE/start-node.ps1" \
|
||||
"$HERE/START-MINING.bat" "$HERE/start-mining.ps1" "$HERE/STOP-IGNEUM.bat" "$HERE/stop-igneum.ps1" \
|
||||
"$HERE/ALLOW-FIREWALL.bat" "$HERE/allow-firewall.ps1" "$HERE/igneum-common.ps1" "$HERE/upload-log.bat" "$HERE/README.txt" "$STAGE/"
|
||||
"$HERE/ALLOW-FIREWALL.bat" "$HERE/allow-firewall.ps1" "$HERE/igneum-common.ps1" "$HERE/upload-log.bat" "$HERE/README.txt" "$HERE/TEST.md" "$STAGE/"
|
||||
cp "$NODE_EXE" "$STAGE/igneumd.exe"
|
||||
cp "$MINER_EXE" "$STAGE/igneum-miner.exe"
|
||||
# The one-click workers and what they need next to them (the exes are static: KERNEL32 and the Universal CRT only)
|
||||
cp "$CUDA_WORKER" "$STAGE/igneum-worker-cuda.exe"
|
||||
cp "$CL_WORKER" "$STAGE/igneum-worker-opencl.exe"
|
||||
cp "$NVRTC_DIR/redist/bin/nvrtc64_120_0.dll" "$NVRTC_DIR/redist/bin/nvrtc-builtins64_128.dll" "$STAGE/"
|
||||
cp "$NVRTC_DIR/redist/LICENSE-NVIDIA-CUDA-EULA.txt" "$NVRTC_DIR/redist/LICENSE-Khronos-OpenCL-Headers.txt" "$NVRTC_DIR/THIRD-PARTY.md" "$STAGE/"
|
||||
MINGW=/opt/homebrew/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32
|
||||
for dll in lib/libstdc++-6.dll lib/libgcc_s_seh-1.dll bin/libwinpthread-1.dll; do
|
||||
name="$(basename "$dll")"
|
||||
|
|
@ -40,7 +55,7 @@ SRC="${IGNEUM_WORKER_SRC:-$ROOT}"
|
|||
cp "$SRC/proto-cuda/host.cu" "$SRC/proto-cuda/build.bat" "$SRC/proto-cuda/README.md" "$STAGE/proto-cuda/"
|
||||
cp "$SRC/proto-opencl/host.c" "$SRC/proto-opencl/build.bat" "$SRC/proto-opencl/README.md" "$SRC/proto-opencl/WAVEFRONT.md" "$STAGE/proto-opencl/"
|
||||
# CRLF for the files Windows tools read as text
|
||||
for f in "$STAGE"/*.bat "$STAGE/README.txt" "$STAGE/proto-cuda/build.bat" "$STAGE/proto-opencl/build.bat"; do
|
||||
for f in "$STAGE"/*.bat "$STAGE/README.txt" "$STAGE/TEST.md" "$STAGE/THIRD-PARTY.md" "$STAGE/proto-cuda/build.bat" "$STAGE/proto-opencl/build.bat"; do
|
||||
perl -pi -e 's/\r?\n/\r\n/' "$f"
|
||||
done
|
||||
rm -f "$OUT"
|
||||
|
|
|
|||
Loading…
Reference in a new issue