From 7b83783983be9fe2e7e0d6f317341306e224f8c8 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Sat, 3 Oct 2026 19:38:22 +0000 Subject: [PATCH] windows-miner: CUDA build finds the MSVC and SDK libraries itself, uploader reads logs in use, deeper toolset search Co-Authored-By: Claude Fable 5.1 --- proto-cuda/build.bat | 23 +++++++++++++++++++++++ proto-cuda/windows-miner/start-mining.ps1 | 2 +- proto-cuda/windows-miner/upload-log.bat | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/proto-cuda/build.bat b/proto-cuda/build.bat index 812743ec..88f49a06 100644 --- a/proto-cuda/build.bat +++ b/proto-cuda/build.bat @@ -34,6 +34,20 @@ if not exist "packs\%PACK%\kernel.cu" ( rem Packs written by igneum-pow or igneum-miner export-pack carry kernel_bound.cu (the header-bound kernel for --serve). set BOUND= if exist "packs\%PACK%\kernel_bound.cu" set BOUND=-DIGNEUM_BOUND "packs\%PACK%\kernel_bound.cu" +rem Find the MSVC runtime libraries and the Windows SDK libraries ourselves and put them in front of LIB: a vcvarsall +rem import can leave LIB without the MSVC lib directory (seen with the 14.30 toolset on Visual Studio 2026), and then +rem nvcc's link step fails with LNK1104 LIBCMT.lib. The newest toolset's libraries link fine with 14.30 objects. +set "MSVCLIB=" +set "SDKLIB=" +set "VSVC=%VCINSTALLDIR%" +if "%VSVC%"=="" set "VSVC=C:\Program Files\Microsoft Visual Studio\18\Community\VC\" +set "KITS=C:\Program Files (x86)\Windows Kits\10\Lib" +for /f "delims=" %%D in ('dir /b /ad /o-n "%VSVC%Tools\MSVC" 2^>nul') do call :msvc "%%D" +for /f "delims=" %%D in ('dir /b /ad /o-n "%KITS%" 2^>nul') do call :sdk "%%D" +if not "%SDKLIB%"=="" set "LIB=%SDKLIB%\ucrt\x64;%SDKLIB%\um\x64;%LIB%" +if not "%MSVCLIB%"=="" set "LIB=%MSVCLIB%;%LIB%" +if "%MSVCLIB%"=="" echo warning: no libcmt.lib under any MSVC toolset; the link step may fail. +echo link libraries: MSVC="%MSVCLIB%" SDK="%SDKLIB%" nvcc --version echo nvcc -O3 -std=c++17 -arch=%ARCH% -allow-unsupported-compiler -I "packs\%PACK%" -o "igneum-bench-cuda-%PACK%.exe" host.cu "packs\%PACK%\kernel.cu" %BOUND% nvcc -O3 -std=c++17 -arch=%ARCH% -allow-unsupported-compiler -I "packs\%PACK%" -o "igneum-bench-cuda-%PACK%.exe" host.cu "packs\%PACK%\kernel.cu" %BOUND% @@ -44,3 +58,12 @@ if errorlevel 1 ( echo built igneum-bench-cuda-%PACK%.exe if not "%BOUND%"=="" echo with --serve support (kernel_bound.cu) endlocal +exit /b 0 +:msvc +if not "%MSVCLIB%"=="" goto :eof +if exist "%VSVC%Tools\MSVC\%~1\lib\x64\libcmt.lib" set "MSVCLIB=%VSVC%Tools\MSVC\%~1\lib\x64" +goto :eof +:sdk +if not "%SDKLIB%"=="" goto :eof +if exist "%KITS%\%~1\ucrt\x64\libucrt.lib" set "SDKLIB=%KITS%\%~1" +goto :eof diff --git a/proto-cuda/windows-miner/start-mining.ps1 b/proto-cuda/windows-miner/start-mining.ps1 index 688e3434..dcb07d00 100644 --- a/proto-cuda/windows-miner/start-mining.ps1 +++ b/proto-cuda/windows-miner/start-mining.ps1 @@ -90,7 +90,7 @@ function Import-VcVars { # Fallback when vcvarsall is unusable: LIB and INCLUDE from the newest MSVC toolset and Windows Kits, as proto-opencl/build.bat does. function Set-LibFallback { $vsRoots = @() - foreach ($pf in @('C:\Program Files', 'C:\Program Files (x86)')) { $vsRoots += Get-ChildItem -Path (Join-Path $pf 'Microsoft Visual Studio') -Directory -Recurse -Depth 3 -Filter 'MSVC' -ErrorAction SilentlyContinue } + foreach ($pf in @('C:\Program Files', 'C:\Program Files (x86)')) { $vsRoots += Get-ChildItem -Path (Join-Path $pf 'Microsoft Visual Studio') -Directory -Recurse -Depth 6 -Filter 'MSVC' -ErrorAction SilentlyContinue } $msvc = $null foreach ($r in $vsRoots) { # Prefer the toolset CUDA accepts (vcvarsVer, 14.30), then the newest one that has the libraries. diff --git a/proto-cuda/windows-miner/upload-log.bat b/proto-cuda/windows-miner/upload-log.bat index 56e558f6..f648d35f 100644 --- a/proto-cuda/windows-miner/upload-log.bat +++ b/proto-cuda/windows-miner/upload-log.bat @@ -20,7 +20,7 @@ set "RUNID=%~3" if "%RUNID%"=="" set "RUNID=%IGNEUM_RUN_ID%" set "OUT=%TEMP%\igneum-upload-%RANDOM%.json" -powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference='Stop'; $b=[IO.File]::ReadAllBytes($env:LOGFILE); $n=[Math]::Min($b.Length,262144); $t=[Text.Encoding]::UTF8.GetString($b,$b.Length-$n,$n); $r=$env:RUNID; if (-not $r) { $r=$env:LABEL + '-' + (Get-Date -Format 'yyyyMMdd-HHmm') }; $o=@{label=$env:LABEL;machine=$env:COMPUTERNAME;run_id=$r;lines=$t}; [IO.File]::WriteAllText($env:OUT,(ConvertTo-Json $o -Compress),(New-Object Text.UTF8Encoding $false)); Write-Host ('upload-log: run_id ' + $r + ', ' + $n + ' bytes')" +powershell -NoProfile -ExecutionPolicy Bypass -Command "$ErrorActionPreference='Stop'; $fs=New-Object IO.FileStream($env:LOGFILE,[IO.FileMode]::Open,[IO.FileAccess]::Read,[IO.FileShare]::ReadWrite); $b=New-Object byte[] $fs.Length; [void]$fs.Read($b,0,$b.Length); $fs.Close(); $n=[Math]::Min($b.Length,262144); $t=[Text.Encoding]::UTF8.GetString($b,$b.Length-$n,$n); $r=$env:RUNID; if (-not $r) { $r=$env:LABEL + '-' + (Get-Date -Format 'yyyyMMdd-HHmm') }; $o=@{label=$env:LABEL;machine=$env:COMPUTERNAME;run_id=$r;lines=$t}; [IO.File]::WriteAllText($env:OUT,(ConvertTo-Json $o -Compress),(New-Object Text.UTF8Encoding $false)); Write-Host ('upload-log: run_id ' + $r + ', ' + $n + ' bytes')" if errorlevel 1 ( echo upload-log: could not read or encode %LOGFILE% exit /b 3