Skip to content

Commit 85228ef

Browse files
Merge pull request #276 from bernardladenthin/claude/windows-gpu-support-xvhi5r
Windows: flip default to Ninja, add MSVC classifier, add GPU classifiers
2 parents e126859 + 2681bde commit 85228ef

10 files changed

Lines changed: 809 additions & 182 deletions

File tree

.github/build.bat

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,28 @@ if /I "%USE_CACHE%"=="true" (
3838
)
3939
)
4040

41+
REM NOTE: nvcc is NOT wrapped with sccache on Windows. Unlike build.sh (Linux) -- where
42+
REM sccache caches the per-arch .cu device passes -- sccache on Windows cannot parse the
43+
REM nvcc command line (it dies with `sccache: error: Could not parse shell line` and
44+
REM fails every .cu compile). So CUDA device code is built by nvcc directly (uncached)
45+
REM here; the cl.exe C/C++ TUs still cache via the C/CXX launcher set above.
46+
4147
mkdir build
4248
cmake -Bbuild %LAUNCH% %*
43-
if errorlevel 1 exit /b %ERRORLEVEL%
49+
if errorlevel 1 exit /b 1
4450
cmake --build build --config Release
45-
if errorlevel 1 exit /b %ERRORLEVEL%
51+
set "BUILD_RC=!ERRORLEVEL!"
4652

47-
REM Only query stats when sccache was actually wired in as the launcher; re-invoking
48-
REM a rejected/crashing sccache here would just repeat its failure output.
53+
REM Print cache stats (best-effort) regardless of build outcome -- only when sccache
54+
REM was wired in as the launcher.
4955
if defined LAUNCH (
5056
echo build.bat: sccache --show-stats
5157
sccache --show-stats
5258
)
59+
60+
REM Propagate a build failure as a non-zero exit (a prior bug let a failed `cmake
61+
REM --build` reach here and exit 0, masquerading as a green build with no artifacts).
62+
if not "!BUILD_RC!"=="0" (
63+
echo build.bat: cmake --build failed with exit code !BUILD_RC!.
64+
exit /b !BUILD_RC!
65+
)

.github/build_opencl_android.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ HEADERS_DIR="$OPENCL_STAGE/OpenCL-Headers"
2020
LOADER_DIR="$OPENCL_STAGE/OpenCL-ICD-Loader"
2121
LOADER_BUILD="$LOADER_DIR/build"
2222

23-
# Pinned tags for reproducibility.
24-
HEADERS_TAG=v2025.07.22
25-
LOADER_TAG=v2025.07.22
23+
# Pinned tags for reproducibility (OpenCL 3.1.1 spec release).
24+
HEADERS_TAG=v2026.05.29
25+
LOADER_TAG=v2026.05.29
2626

2727
if [ ! -d "$HEADERS_DIR" ]; then
2828
mkdir -p "$OPENCL_STAGE"

.github/build_opencl_windows.bat

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
REM SPDX-FileCopyrightText: 2026 Bernard Ladenthin <bernard.ladenthin@gmail.com>
2+
REM
3+
REM SPDX-License-Identifier: MIT
4+
REM
5+
REM Windows x86_64 build with the OpenCL backend enabled, shipped as the
6+
REM `opencl-windows-x86-64` classifier. The windows-2025 runner image ships
7+
REM neither OpenCL headers nor an OpenCL import library, so this script first
8+
REM stages Khronos OpenCL-Headers and builds OpenCL-ICD-Loader (producing
9+
REM OpenCL.lib) before delegating the jllama configure+build to build.bat with
10+
REM the OpenCL paths. Mirrors build_opencl_android.sh.
11+
REM
12+
REM At runtime the GPU vendor's ICD (System32\OpenCL.dll, installed by the
13+
REM NVIDIA/AMD/Intel driver) provides the actual OpenCL symbols; we link only
14+
REM against the loader's import library, so no OpenCL.dll is shipped.
15+
16+
@echo off
17+
setlocal enabledelayedexpansion
18+
19+
set "OPENCL_STAGE=%RUNNER_TEMP%\opencl-stage"
20+
if "%RUNNER_TEMP%"=="" set "OPENCL_STAGE=%TEMP%\opencl-stage"
21+
set "HEADERS_DIR=%OPENCL_STAGE%\OpenCL-Headers"
22+
set "LOADER_DIR=%OPENCL_STAGE%\OpenCL-ICD-Loader"
23+
set "LOADER_BUILD=%LOADER_DIR%\build"
24+
25+
REM Pinned tags for reproducibility (OpenCL 3.1.1; match build_opencl_android.sh).
26+
set "HEADERS_TAG=v2026.05.29"
27+
set "LOADER_TAG=v2026.05.29"
28+
29+
if not exist "%HEADERS_DIR%" (
30+
git clone --depth 1 --branch %HEADERS_TAG% https://github.com/KhronosGroup/OpenCL-Headers.git "%HEADERS_DIR%"
31+
if errorlevel 1 exit /b 1
32+
)
33+
34+
if not exist "%LOADER_BUILD%\Release\OpenCL.lib" if not exist "%LOADER_BUILD%\OpenCL.lib" (
35+
if not exist "%LOADER_DIR%" (
36+
git clone --depth 1 --branch %LOADER_TAG% https://github.com/KhronosGroup/OpenCL-ICD-Loader.git "%LOADER_DIR%"
37+
if errorlevel 1 exit /b 1
38+
)
39+
cmake -B "%LOADER_BUILD%" -S "%LOADER_DIR%" -DOPENCL_ICD_LOADER_HEADERS_DIR="%HEADERS_DIR%" -DBUILD_TESTING=OFF
40+
if errorlevel 1 exit /b 1
41+
cmake --build "%LOADER_BUILD%" --config Release
42+
if errorlevel 1 exit /b 1
43+
)
44+
45+
REM Resolve the import library: multi-config generators emit build\Release\OpenCL.lib,
46+
REM single-config ones emit build\OpenCL.lib.
47+
set "OPENCL_LIB=%LOADER_BUILD%\Release\OpenCL.lib"
48+
if not exist "%OPENCL_LIB%" set "OPENCL_LIB=%LOADER_BUILD%\OpenCL.lib"
49+
50+
REM Delegate to build.bat so the jllama build inherits the sccache probe + Depot
51+
REM cache launcher and --show-stats output. The OpenCL paths satisfy ggml's
52+
REM find_package(OpenCL); the caller appends -G/-DGGML_OPENCL/-DOS_* via %*.
53+
call .github\build.bat -DOpenCL_INCLUDE_DIR="%HEADERS_DIR%" -DOpenCL_LIBRARY="%OPENCL_LIB%" %*
54+
exit /b %ERRORLEVEL%

0 commit comments

Comments
 (0)