igneum/proto-cuda/nvrtc/build-windows.sh
igneum-labs fe852a4335 AMD telemetry: igneum-gpu-telemetry (ADLX on Windows, amdgpu sysfs on Linux, PDH utilisation fallback) feeds the card row's draw, temperature, fan, memory clock and MH/W; measured on PC 1: 9070 XT 198.9 W, 64 C, 657 rpm, 17.73 MH/s = 0.089 MH/W beside the 5090 at 307.6 W, 122.30 MH/s = 0.398 MH/W
the project lead watched the 9070 XT at 90% usage with its fans barely turning and the app could not say what it drew: the
draw, temperature and MH per watt line came from nvidia-smi only, and the earlier per-watt figure used the board
rating. proto-opencl/gpu-telemetry.c prints one line per AMD card per sample (bus from SetupAPI by the display
device's name, kind, name, watts, temp_c, fan_rpm, fan_pct, mclk_mhz, gclk_mhz, util_pct, source), built by
build-windows.sh against vendor/adlx (the SDK clone), shipped by make-payload.sh and push-inputs.sh. The engine
runs it with -l 5 beside nvidia-smi (Source::AmdTelemetry, tick_amd_telemetry), parse_amd_telemetry fills
power_w, temp_gpu, fan_pct, fan_rpm, mclk_mhz, util_pct and telemetry_at on the AMD card matched by kind and
ordinal, so eff_mhw and the dashboard's existing line show it; app.js shows fan and memory clock when present.
Tests: three on the parser with lines captured on PC 1 and the Mac fixture; the sysfs path ran on a fixture tree.

Measured over 20:27:45 to 20:29:41 UTC with both cards mining (docs/bench-log.md, under the 9070 XT ceiling table):
9070 XT 198.9 W (193 to 212), 64 C, 657 rpm, 2,505 MHz memory, 3,290 MHz shader, 100% busy, 17.73 MH/s =
0.089 MH/W; RTX 5090 307.6 W, 69 C, 44% fan, 122.30 MH/s = 0.398 MH/W.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 20:43:21 +00:00

52 lines
3.9 KiB
Bash
Executable file

#!/usr/bin/env bash
# Cross-compiles the two one-click Windows workers on the Mac with Homebrew mingw-w64 (x86_64-w64-mingw32-gcc/g++):
# proto-cuda/nvrtc/igneum-worker-cuda.exe driver API + NVRTC, both loaded at run time (cuda_api.h); needs cuda.h and
# nvrtc.h from fetch-redist.sh to compile, no import library
# proto-opencl/igneum-worker-opencl.exe host.c with IGNEUM_CL_DYNAMIC (OpenCL.dll loaded at run time) and the generic
# --pack serve mode; the pack it is built against is only a placeholder
# Static libgcc/libstdc++/winpthread, so each exe needs only KERNEL32 and the Universal CRT (Windows 10 and 11 have it).
# Each exe carries the coin icon and a version block (igneum-worker-cuda.rc, igneum-worker-opencl.rc, compiled with windres
# and linked in; the project lead's rule, 4 October 2026: every shipped exe shows the coin in Explorer and a publisher in Properties).
# Usage: build-windows.sh (then windows-app/make-package.sh ships them with the NVRTC DLLs)
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$HERE/../.." && pwd)"
RED="$HERE/redist"
ICONS="$ROOT/brand/icons"
[ -f "$RED/include/cuda.h" ] && [ -f "$RED/include/nvrtc.h" ] && [ -f "$RED/include/CL/cl.h" ] || { echo "run $HERE/fetch-redist.sh first" >&2; exit 1; }
CXX=x86_64-w64-mingw32-g++
CC=x86_64-w64-mingw32-gcc
STRIP=x86_64-w64-mingw32-strip
WINDRES=x86_64-w64-mingw32-windres
command -v "$WINDRES" >/dev/null || { echo "$WINDRES not found (brew install mingw-w64)" >&2; exit 1; }
PLACEHOLDER="$ROOT/proto-cuda/packs/igneum-devnet-v4-epoch0"
VERIFY="$ROOT/packaging/windows/resources/verify-exe.py"
# The coin icon and the version blocks, as COFF objects the linker takes like any other input
[ -f "$ICONS/igneum.ico" ] || { echo "== no $ICONS/igneum.ico, making the icons"; python3 "$ICONS/make-icons.py"; }
RES="$(mktemp -d)"
for w in cuda opencl gpu-telemetry; do
"$WINDRES" -I "$ICONS" -i "$HERE/igneum-worker-$w.rc" -O coff -o "$RES/igneum-worker-$w.res.o"
done
echo "== igneum-worker-cuda.exe"
"$CXX" -std=c++17 -O2 -Wall -Wextra -static -I "$HERE" -I "$RED/include" -o "$HERE/igneum-worker-cuda.exe" "$HERE/worker.cpp" "$RES/igneum-worker-cuda.res.o"
"$STRIP" "$HERE/igneum-worker-cuda.exe"
echo "== igneum-worker-opencl.exe"
"$CC" -std=c99 -O2 -Wall -Wextra -Wno-stringop-truncation -Wno-format-truncation -static -DIGNEUM_CL_DYNAMIC -DCL_TARGET_OPENCL_VERSION=120 \
-I "$RED/include" -I "$PLACEHOLDER" -DIGNEUM_KERNEL_PATH='"kernel_bound.cl"' \
-o "$ROOT/proto-opencl/igneum-worker-opencl.exe" "$ROOT/proto-opencl/host.c" "$RES/igneum-worker-opencl.res.o"
"$STRIP" "$ROOT/proto-opencl/igneum-worker-opencl.exe"
echo "== igneum-gpu-telemetry.exe (ADLX, SetupAPI, PDH; vendor/adlx is the SDK clone)"
[ -f "$ROOT/vendor/adlx/SDK/Include/ADLX.h" ] || { echo "no vendor/adlx: git clone --depth 1 https://github.com/GPUOpen-LibrariesAndSDKs/ADLX.git $ROOT/vendor/adlx" >&2; exit 1; }
"$CC" -std=gnu99 -O2 -Wall -Wno-unused-parameter -Wno-unused-function -static -I "$ROOT/vendor/adlx/SDK/Include" \
-o "$ROOT/proto-opencl/igneum-gpu-telemetry.exe" "$ROOT/proto-opencl/gpu-telemetry.c" "$ROOT/vendor/adlx/SDK/ADLXHelper/Windows/C/ADLXHelper.c" "$RES/igneum-worker-gpu-telemetry.res.o" -lsetupapi -lpdh
"$STRIP" "$ROOT/proto-opencl/igneum-gpu-telemetry.exe"
rm -rf "$RES"
for exe in "$HERE/igneum-worker-cuda.exe" "$ROOT/proto-opencl/igneum-worker-opencl.exe" "$ROOT/proto-opencl/igneum-gpu-telemetry.exe"; do
printf '%s: %d bytes, imports:' "$(basename "$exe")" "$(stat -f %z "$exe")"
x86_64-w64-mingw32-objdump -p "$exe" | sed -n 's/^[[:space:]]*DLL Name: //p' | tr '\n' ' '
echo
done
# the icon and version block survived the strip (strip keeps .rsrc; this proves it)
python3 "$VERIFY" --version 0.3.0 "$HERE/igneum-worker-cuda.exe" "$ROOT/proto-opencl/igneum-worker-opencl.exe" "$ROOT/proto-opencl/igneum-gpu-telemetry.exe"