Add MLX backend for Apple Silicon (GPU + ANE) #247
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Test | |
| on: | |
| push: | |
| branches: [ master ] | |
| pull_request: | |
| branches: [ master ] | |
| workflow_dispatch: | |
| jobs: | |
| build-linux: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential zlib1g-dev libzip-dev opencl-headers ocl-icd-opencl-dev | |
| - name: Cache CMake build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| cpp/CMakeCache.txt | |
| cpp/CMakeFiles | |
| key: ${{ runner.os }}-cmake-${{ hashFiles('**/CMakeLists.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cmake- | |
| - name: Configure CMake | |
| working-directory: cpp | |
| run: | | |
| cmake . -DUSE_BACKEND=OPENCL -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS_RELEASE="-s" | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| make -j$(nproc) | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| ./katago runtests | |
| - name: Upload artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: katago-linux-opencl | |
| path: cpp/katago | |
| # Compile-only ROCm check: GitHub runners have no AMD GPU, but the ROCm backend builds | |
| # fine without one and runtests exercises no GPU code. Pinned to ROCm 6.4 (the documented | |
| # minimum supported version) so this also catches changes that compile on newer ROCm but | |
| # break the oldest supported one's headers/APIs. | |
| # Three things this does not cover. The Composable Kernel fused attention glue is skipped, | |
| # because ck_tile's headers come from the composablekernel-dev package and nothing installed | |
| # below depends on it, so the configure takes its "ck_tile headers not found" branch and builds | |
| # only the built-in attention kernels. The newer ROCm versions that the Windows and TheRock | |
| # paths are developed against are not built here either. Nor is anything run on a GPU. | |
| build-linux-rocm: | |
| # Pinned rather than ubuntu-latest: the apt source line below is release-specific ("noble"). | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free disk space | |
| # The ROCm dev packages unpack to ~11 GB (mostly rocBLAS/MIOpen kernel libraries), so | |
| # clear unrelated preinstalled toolchains to make room on the runner's root disk. | |
| run: | | |
| sudo rm -rf /usr/local/lib/android /usr/share/dotnet | |
| - name: Install ROCm 6.4 and build dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake build-essential zlib1g-dev libzip-dev wget gnupg | |
| sudo mkdir -p /etc/apt/keyrings | |
| wget -q https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | sudo tee /etc/apt/keyrings/rocm.gpg > /dev/null | |
| echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/6.4.3 noble main" | sudo tee /etc/apt/sources.list.d/rocm.list | |
| # AMD's documented apt pin. Without it, Ubuntu's own ancient standalone "hipcc" | |
| # package (which installs to /usr/bin) outversions repo.radeon.com's, and the HIP | |
| # cmake config then fails on the missing /opt/rocm/bin/hipcc. | |
| printf 'Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600\n' | sudo tee /etc/apt/preferences.d/rocm-pin-600 | |
| sudo apt-get update | |
| sudo apt-get install -y hip-dev hipcc hipblas-dev miopen-hip-dev | |
| - name: Configure CMake | |
| working-directory: cpp | |
| run: | | |
| # One CDNA/wave64 arch (gfx942) and one RDNA3/wave32 arch (gfx1100): with no GPU | |
| # present, the arch list only determines which device code gets compiled, so this | |
| # covers both wavefront-size compile paths. | |
| cmake . -DUSE_BACKEND=ROCM -DCMAKE_HIP_ARCHITECTURES="gfx942;gfx1100" -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| make -j$(nproc) | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| ./katago version | |
| ./katago runtests | |
| # Compile-only Windows ROCm check via AMD TheRock (the toolchain Compiling.md documents for | |
| # Windows). No AMD GPU on the runner, so this covers configure+compile+link and the GPU-less | |
| # runtests only - not GPU execution. Uses a pinned TheRock nightly dist tarball. Bump the | |
| # version below deliberately, since toolchain drift is exactly what this job is meant to catch. | |
| # The Composable Kernel fused attention path is not covered at the version pinned below, whose | |
| # ck_tile the configure-time probe rejects on Windows (see | |
| # external/composable_kernel_fmha/README.md). This is specific to that ck_tile rather than to | |
| # Windows or MSVC in general, and earlier TheRock versions do build the CK kernels here, so on a | |
| # version where the probe accepts them this job covers them too. | |
| build-windows-rocm: | |
| # windows-2022: KataGo's CMake requires a v143 MSVC toolset (14.3x/14.4x) for HIP clang | |
| # compatibility, which this image ships. | |
| runs-on: windows-2022 | |
| timeout-minutes: 90 | |
| permissions: | |
| contents: read | |
| env: | |
| THEROCK_VERSION: 7.14.0a20260612 | |
| THEROCK_FAMILY: gfx110X-all | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Cache TheRock tarball | |
| id: cache-therock | |
| uses: actions/cache@v4 | |
| with: | |
| path: C:\TheRock\therock-dist.tar.gz | |
| key: therock-windows-${{ env.THEROCK_FAMILY }}-${{ env.THEROCK_VERSION }} | |
| - name: Download TheRock dist tarball | |
| if: steps.cache-therock.outputs.cache-hit != 'true' | |
| run: | | |
| New-Item -ItemType Directory -Force -Path C:\TheRock | Out-Null | |
| curl.exe -fsSL --retry 3 -o C:\TheRock\therock-dist.tar.gz ` | |
| "https://therock-nightly-tarball.s3.amazonaws.com/therock-dist-windows-$env:THEROCK_FAMILY-$env:THEROCK_VERSION.tar.gz" | |
| - name: Extract TheRock | |
| run: | | |
| New-Item -ItemType Directory -Force -Path C:\TheRock\build | Out-Null | |
| tar -xzf C:\TheRock\therock-dist.tar.gz -C C:\TheRock\build | |
| - name: Set ROCm environment (per Compiling.md) | |
| run: | | |
| Add-Content $env:GITHUB_ENV "HIP_PATH=C:/TheRock/build" | |
| Add-Content $env:GITHUB_ENV "HIP_PLATFORM=amd" | |
| Add-Content $env:GITHUB_ENV "HIP_DEVICE_LIB_PATH=C:/TheRock/build/lib/llvm/amdgcn/bitcode" | |
| Add-Content $env:GITHUB_ENV "LLVM_PATH=C:/TheRock/build/lib/llvm" | |
| Add-Content $env:GITHUB_PATH "C:\TheRock\build\bin" | |
| Add-Content $env:GITHUB_PATH "C:\TheRock\build\lib\llvm\bin" | |
| - name: Install Ninja | |
| run: choco install ninja -y --no-progress | |
| - name: Configure CMake | |
| working-directory: cpp | |
| # Single arch matching the tarball's gfx family - with no GPU present the arch list only | |
| # determines which device code gets compiled. zlib is auto-fetched at configure time via | |
| # the KATAGO_AUTO_FETCH_DEPS vcpkg mechanism (needs network + git, both present here). | |
| # libzip is optional and auto-disables. | |
| run: | | |
| cmake . -G Ninja -DUSE_BACKEND=ROCM -DCMAKE_HIP_ARCHITECTURES=gfx1100 -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| ninja | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| .\katago.exe version | |
| .\katago.exe runtests | |
| build-macos: | |
| runs-on: macos-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| brew install zlib libzip opencl-headers | |
| # CMake resolves find_package(ZLIB) to the SDK's libz.tbd and bakes its | |
| # absolute path (e.g. .../Xcode_16.4.app/.../MacOSX.sdk/usr/lib/libz.tbd) | |
| # into the cached build.ninja/CMakeCache.txt. When GitHub bumps the | |
| # runner's default Xcode that path disappears and the cached ninja build | |
| # fails. Fold the Xcode version into the cache key so a bump forces a | |
| # fresh configure. | |
| - name: Capture toolchain version for cache key | |
| id: xcode-version | |
| run: | | |
| echo "xcode=$(xcodebuild -version | tr '\n' '-')" >> "$GITHUB_OUTPUT" | |
| - name: Cache CMake build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| cpp/CMakeCache.txt | |
| cpp/CMakeFiles | |
| cpp/build.ninja | |
| cpp/.ninja_deps | |
| cpp/.ninja_log | |
| key: ${{ runner.os }}-cmake-${{ steps.xcode-version.outputs.xcode }}-${{ hashFiles('**/CMakeLists.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cmake-${{ steps.xcode-version.outputs.xcode }}- | |
| - name: Configure CMake | |
| working-directory: cpp | |
| run: | | |
| cmake . -G Ninja -DUSE_BACKEND=OPENCL -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| ninja | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| ./katago runtests | |
| - name: Upload artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: katago-macos-opencl | |
| path: cpp/katago | |
| build-macos-metal: | |
| runs-on: macos-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| brew install ninja zlib libzip protobuf abseil | |
| # The CMake build (build.ninja, CMakeCache.txt) bakes in version-pinned | |
| # Homebrew Cellar paths for protobuf/abseil (e.g. | |
| # -L/opt/homebrew/Cellar/protobuf/34.1/lib). When Homebrew bumps those | |
| # the cached paths go stale and the link fails. | |
| # Capture the installed versions into the cache key so | |
| # a formula bump invalidates the cache and forces a fresh configure. | |
| # Also fold in the Xcode version: CMake bakes the SDK's absolute | |
| # libz.tbd path into the cached build, so an Xcode bump on the runner | |
| # leaves a stale path and breaks the cached ninja build. | |
| - name: Capture dependency versions for cache key | |
| id: dep-versions | |
| run: | | |
| echo "versions=$(brew list --versions protobuf abseil | tr '\n' '-')$(xcodebuild -version | tr '\n' '-')" >> "$GITHUB_OUTPUT" | |
| - name: Cache CMake build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| cpp/CMakeCache.txt | |
| cpp/CMakeFiles | |
| cpp/build.ninja | |
| cpp/.ninja_deps | |
| cpp/.ninja_log | |
| key: ${{ runner.os }}-cmake-metal-${{ steps.dep-versions.outputs.versions }}-${{ hashFiles('**/CMakeLists.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cmake-metal-${{ steps.dep-versions.outputs.versions }}- | |
| - name: Configure CMake | |
| working-directory: cpp | |
| run: | | |
| cmake . -G Ninja -DUSE_BACKEND=METAL -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| ninja | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| ./katago runtests | |
| - name: Upload artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: katago-macos-metal | |
| path: cpp/katago | |
| build-macos-mlx: | |
| # macos-latest is Apple Silicon (arm64), which the MLX backend requires. | |
| runs-on: macos-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| brew install ninja zlib libzip protobuf abseil mlx | |
| # The CMake build (build.ninja, CMakeCache.txt) bakes in version-pinned | |
| # Homebrew Cellar paths for protobuf/abseil/mlx (e.g. | |
| # -L/opt/homebrew/Cellar/mlx/0.31.2/lib). When Homebrew bumps those | |
| # the cached paths go stale and the link fails. | |
| # Capture the installed versions into the cache key so | |
| # a formula bump invalidates the cache and forces a fresh configure. | |
| - name: Capture dependency versions for cache key | |
| id: dep-versions | |
| run: | | |
| echo "versions=$(brew list --versions protobuf abseil mlx | tr '\n' '-')" >> "$GITHUB_OUTPUT" | |
| - name: Cache CMake build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| cpp/CMakeCache.txt | |
| cpp/CMakeFiles | |
| cpp/build.ninja | |
| cpp/.ninja_deps | |
| cpp/.ninja_log | |
| key: ${{ runner.os }}-cmake-mlx-${{ steps.dep-versions.outputs.versions }}-${{ hashFiles('**/CMakeLists.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cmake-mlx-${{ steps.dep-versions.outputs.versions }}- | |
| - name: Configure CMake | |
| working-directory: cpp | |
| run: | | |
| cmake . -G Ninja -DUSE_BACKEND=MLX -DCMAKE_BUILD_TYPE=Release | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| ninja | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| ./katago runtests | |
| - name: Upload artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: katago-macos-mlx | |
| path: cpp/katago | |
| build-windows: | |
| runs-on: windows-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup MSVC | |
| uses: microsoft/setup-msbuild@v2 | |
| - name: Cache vcpkg packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ${{ env.VCPKG_INSTALLATION_ROOT }}/installed | |
| ${{ env.VCPKG_INSTALLATION_ROOT }}/packages | |
| key: ${{ runner.os }}-vcpkg-${{ hashFiles('**/vcpkg.json') }}-opencl | |
| restore-keys: | | |
| ${{ runner.os }}-vcpkg- | |
| - name: Install vcpkg dependencies | |
| run: | | |
| vcpkg install zlib:x64-windows libzip:x64-windows opencl:x64-windows | |
| - name: Configure CMake | |
| working-directory: cpp | |
| run: | | |
| cmake . -A x64 ` | |
| -DUSE_BACKEND=OPENCL ` | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" | |
| - name: Build | |
| working-directory: cpp | |
| run: | | |
| cmake --build . --config Release -j 4 | |
| - name: Copy required DLLs | |
| working-directory: cpp | |
| run: | | |
| $vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT | |
| Copy-Item "$vcpkgRoot/installed/x64-windows/bin/*.dll" -Destination "Release/" | |
| - name: Run tests | |
| working-directory: cpp | |
| run: | | |
| Release/katago.exe runtests | |
| - name: Upload artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: katago-windows-opencl | |
| path: cpp/Release/ |