proto-cuda/nvrtc/worker.cpp serves igneum-miner's worker protocol with nothing installed but the NVIDIA driver: nvcuda.dll and the redistributable nvrtc64_120_0.dll are opened with LoadLibrary (cuda_api.h), the pack's kernel.cu and kernel_bound.cu are handed to NVRTC byte for byte up to the host launch wrappers with program.h and memhard.h as named headers, every pack is self-tested against its vectors.h (cache head, last line, FNV-1a 64, dataset head, last word, 64 samples, 96 vector lanes) before it serves a job, prepare runs on a thread for the hourly swap, and a job on seeds without a pair makes the worker find the miner's pack by seeds.txt and build it. packfile.h (C99) reads a pack directory. fetch-redist.sh verifies and stages the NVIDIA 12.8.93 redistributables and the Khronos headers (THIRD-PARTY.md records URLs, hashes and the EULA clause); build-windows.sh cross-compiles with mingw (static, KERNEL32 + Universal CRT only). emu/: the two libraries as host functions, the pack kernels on host threads, the NVRTC source compared with the pack files; test.sh PASS on the Mac (two real packs, swap, self-heal, 17 sampled hashes equal igneum-pow hash-bound). Not run here: the real NVRTC compile and driver load (RTX 5090 PC). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
62 lines
4.1 KiB
Bash
Executable file
62 lines
4.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# The protocol check shared by the CUDA emulation (test.sh) and the OpenCL generic worker (proto-opencl/test-generic.sh):
|
|
# drives one worker through two jobs on pack A (one across the 32-bit nonce boundary), a background prepare of pack B,
|
|
# the swap, a refused job on A after the swap, and compares a sample of the found hashes with igneum-pow hash-bound.
|
|
# Usage: serve-check.sh <pack A dir> <pack B dir> <log file> <worker command...>
|
|
# The worker command is run as given plus the stdin script; it must already carry --serve --pack <pack A> etc.
|
|
set -euo pipefail
|
|
PACK_A="$1"; PACK_B="$2"; LOG="$3"; shift 3
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
ROOT="$(cd "$HERE/../../.." && pwd)"
|
|
POW="$ROOT/igneum-pow/target/release/igneum-pow"
|
|
seedline() { sed -n "s/^$2 //p" "$1/seeds.txt"; }
|
|
A_EPOCH="$(seedline "$PACK_A" epoch_seed_hex)"; A_DAY="$(seedline "$PACK_A" day_seed_hex)"
|
|
B_EPOCH="$(seedline "$PACK_B" epoch_seed_hex)"; B_DAY="$(seedline "$PACK_B" day_seed_hex)"
|
|
WAIT="${IGNEUM_PREPARE_WAIT:-40}"
|
|
PRE="0000000000000000000000000000000000000000000000000000000000000001"
|
|
{
|
|
echo "job 1 $PRE ffffffffffffffff 0 64 $A_EPOCH $A_DAY"
|
|
echo "job 2 $PRE ffffffffffffffff 4294967264 64 $A_EPOCH $A_DAY"
|
|
echo "prepare $B_EPOCH $B_DAY $PACK_B"
|
|
sleep "$WAIT"
|
|
echo "job 3 $PRE ffffffffffffffff 128 32 $A_EPOCH $A_DAY"
|
|
sleep 1
|
|
echo "job 4 $PRE ffffffffffffffff 0 32 $B_EPOCH $B_DAY"
|
|
echo "job 5 $PRE ffffffffffffffff 96 32 $A_EPOCH $A_DAY"
|
|
echo "quit"
|
|
} | "$@" | tee "$LOG"
|
|
|
|
echo "== verdict"
|
|
bad=0; n=0
|
|
check() { # job nonce epoch day
|
|
want="$("$POW" hash-bound --prehash "$PRE" --nonce "$2" --epoch-hex "$3" --day-hex "$4" | tail -1)"
|
|
got="$(grep "^found $1 $2 " "$LOG" | awk '{print $4}')"
|
|
n=$((n + 1))
|
|
if [ "$want" != "$got" ]; then echo "MISMATCH job $1 nonce $2: worker $got cpu $want"; bad=$((bad + 1)); fi
|
|
}
|
|
grep -q '^ready .* prepare 1 ' "$LOG" || { echo "FAIL: no ready line with prepare 1"; exit 1; }
|
|
[ "$(grep -c '^found 1 ' "$LOG")" = 64 ] || { echo "FAIL: job 1 should find 64"; exit 1; }
|
|
[ "$(grep -c '^found 2 ' "$LOG")" = 64 ] || { echo "FAIL: job 2 should find 64"; exit 1; }
|
|
[ "$(grep -c '^found 3 ' "$LOG")" = 32 ] || { echo "FAIL: job 3 should find 32"; exit 1; }
|
|
[ "$(grep -c '^found 4 ' "$LOG")" = 32 ] || { echo "FAIL: job 4 should find 32 (was pack B prepared in time? IGNEUM_PREPARE_WAIT=$WAIT s)"; exit 1; }
|
|
grep -q "^prepared $B_EPOCH $B_DAY .*self-test PASS" "$LOG" || { echo "FAIL: no prepared line with self-test PASS"; exit 1; }
|
|
grep -q '^info switched to the prepared pair' "$LOG" || { echo "FAIL: no swap"; exit 1; }
|
|
# Job 5 is on pack A after the swap dropped it: an ahead-of-time worker refuses it (OpenCL host.c), the CUDA worker
|
|
# self-heals by finding pack A next to its first pack and building it again in the foreground (32 found, 5 done lines).
|
|
if grep -q '^error 5 epoch seed mismatch' "$LOG"; then
|
|
job5="refused (no pair for its seeds)"
|
|
[ "$(grep -c '^done ' "$LOG")" = 4 ] || { echo "FAIL: 4 done lines expected"; exit 1; }
|
|
elif grep -q '^info job 5 is for epoch .* building its pack' "$LOG" && [ "$(grep -c '^found 5 ' "$LOG")" = 32 ]; then
|
|
job5="served after the worker rebuilt pack A by itself (self-heal)"
|
|
[ "$(grep -c '^done ' "$LOG")" = 5 ] || { echo "FAIL: 5 done lines expected"; exit 1; }
|
|
for x in 96 127; do check 5 $x "$A_EPOCH" "$A_DAY"; done 2>/dev/null || true
|
|
else
|
|
echo "FAIL: job 5 was neither refused nor self-healed"; exit 1
|
|
fi
|
|
grep -q '^found 2 4294967295 ' "$LOG" && grep -q '^found 2 4294967296 ' "$LOG" || { echo "FAIL: the 32-bit boundary nonces are missing"; exit 1; }
|
|
for x in 0 1 2 31 32 63; do check 1 $x "$A_EPOCH" "$A_DAY"; done
|
|
for x in 4294967264 4294967295 4294967296 4294967327; do check 2 $x "$A_EPOCH" "$A_DAY"; done
|
|
for x in 128 159; do check 3 $x "$A_EPOCH" "$A_DAY"; done
|
|
for x in 0 7 31; do check 4 $x "$B_EPOCH" "$B_DAY"; done
|
|
[ "$bad" = 0 ] || { echo "FAIL: $bad of $n sampled hashes differ from igneum-pow"; exit 1; }
|
|
echo "PASS: ready + prepare 1; 64 + 64 + 32 found on pack A, prepared B with self-test PASS, swapped, 32 found on B, job 5 $job5; $n sampled hashes (both packs, both sides of the 32-bit nonce boundary) equal igneum-pow hash-bound"
|