From de3b1563c59586a7b19361ce0432e02b59ccb7b6 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Wed, 22 Jul 2026 19:26:01 -0400 Subject: [PATCH 1/5] Port macOS testing to GitHub Actions Still in draft mode. Outstanding work: 1. WebGPU via Dawn 2. Remove continue-on-error once the apps pass CI 3. Adding x86 Also this runs coverage on main and should heal the CodeCov bot. --- .github/workflows/testing-macos.yml | 120 +++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 9 deletions(-) diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index 803c122eb78b..2ba8105f230a 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -1,6 +1,12 @@ name: macOS on: + # Codecov needs a coverage run on main itself (not just PR branches) to + # compute diffs correctly under our squash-and-merge strategy -- otherwise + # it has no base-commit report to diff a PR's coverage against. Only the + # `coverage` job runs on push; `macos` stays pull_request-only. + push: + branches: [ main ] pull_request: types: [ opened, synchronize, reopened ] paths-ignore: @@ -50,16 +56,21 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} macos: - if: "!contains(github.event.pull_request.labels.*.name, 'skip_buildbots')" + if: "github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'skip_buildbots')" name: ${{ matrix.arch }} / ${{ matrix.uv_group }} runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - # Disable extra cases until we have a fuller workflow - # For now, we're only testing HelloiOS - uv_group: [ "ci-llvm-main", ] # "ci-llvm-22", "ci-llvm-21" - runner: [ "macos-26", ] # "macos-26-intel" + # macOS is only tested against LLVM main (matches Buildbot's own + # choice -- macOS never gets the multi-LLVM matrix that Linux/Windows + # do, since that's a 3x cost multiplier on the most expensive + # runner tier). + uv_group: [ "ci-llvm-main" ] + # x86-64 (macos-26-intel) is a follow-up: needs the runner label's + # availability verified, plus the x86-64-osx/-sse41 correctness-only + # passes and ENABLE_APPS_HANNK=OFF (no tflite on x86 macOS). + runner: [ "macos-26" ] include: - runner: macos-26 arch: arm-64 @@ -70,6 +81,9 @@ jobs: - uses: astral-sh/setup-uv@v7 + - name: Install wasm toolchain + run: brew install emscripten wabt + - name: Sync CI environment run: | uv sync --python '${{ matrix.python }}' --group '${{ matrix.uv_group }}' --no-install-project @@ -83,14 +97,49 @@ jobs: run: >- cmake --preset ci-macos-${{ matrix.arch }} -DCMAKE_INSTALL_PREFIX="${{ github.workspace }}/install" - -DWITH_TESTS=NO - -DWITH_UTILS=NO - -DWITH_TUTORIALS=NO - -DWITH_PYTHON_BINDINGS=NO - name: Initial build run: cmake --build build --target install + # --- host: internal, correctness, generator, error, warning, + # tutorial, python, autoschedulers_cpu --- + + - name: Test (host) + run: | + cmake -S . -B build -DHalide_TARGET=host + cmake --build build --target install + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -LE "performance|autoschedulers" -j "$(sysctl -n hw.logicalcpu)" \ + -E tutorial_lesson_19 + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L "performance|autoschedulers" --repeat until-pass:5 + + # --- apps/ (host): first time apps/ is exercised via ctest in any of + # the CMake-preset GHA workflows (only the legacy Make-based + # testing-make.yml does today), so keep this non-blocking until proven + # green. --- + + - name: Configure apps (host) + continue-on-error: true + run: >- + cmake -S apps -B apps-build + -G Ninja + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install" + -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" + -DHalide_TARGET=host + -DENABLE_APPS_HANNK=ON + + - name: Build apps (host) + continue-on-error: true + run: cmake --build apps-build + + - name: Test apps (host) + continue-on-error: true + run: >- + ctest --test-dir apps-build --build-config RelWithDebInfo + --output-on-failure -LE slow_tests --timeout 3600 + - name: Configure HelloiOS run: ./setup.sh working-directory: apps/HelloiOS @@ -105,3 +154,56 @@ jobs: -destination 'generic/platform=iOS Simulator' build working-directory: apps/HelloiOS + + # --- host-metal: real GPU testing on hosted Apple Silicon runners --- + + - name: Test (host-metal) + run: | + cmake -S . -B build -DHalide_TARGET=host-metal + cmake --build build --target install + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L "correctness|generator" -j "$(sysctl -n hw.logicalcpu)" + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L "performance|autoschedulers_gpu" --repeat until-pass:5 + + - name: Configure apps (host-metal) + continue-on-error: true + run: >- + cmake -S apps -B apps-build + -G Ninja + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install" + -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" + -DHalide_TARGET=host-metal + -DENABLE_APPS_HANNK=ON + + - name: Build apps (host-metal) + continue-on-error: true + run: cmake --build apps-build + + - name: Test apps (host-metal) + continue-on-error: true + run: >- + ctest --test-dir apps-build --build-config RelWithDebInfo + --output-on-failure -LE slow_tests --timeout 3600 + + # --- wasm (wabt JIT) --- + + - name: Test (wasm_simd128, wabt JIT) + run: | + cmake -S . -B build -DHalide_TARGET=wasm-32-wasmrt-wasm_simd128 + cmake --build build + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L "internal|correctness|generator|error|warning" -j "$(sysctl -n hw.logicalcpu)" + + - name: Test (wasm_mvponly, wabt JIT) + run: | + cmake -S . -B build -DHalide_TARGET=wasm-32-wasmrt-wasm_mvponly + cmake --build build + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L "internal|correctness|generator|error|warning" -j "$(sysctl -n hw.logicalcpu)" + + - name: Build (wasm_simd128 + wasm_threads, generator only) + run: | + cmake -S . -B build -DHalide_TARGET=wasm-32-wasmrt-wasm_simd128-wasm_threads + cmake --build build --target build_generator From e2432f4d920aa10518cbb699601b109f1221f7ef Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Wed, 22 Jul 2026 22:13:00 -0400 Subject: [PATCH 2/5] Trim leaked fuzz tests, unblock apps/, and add x86-64 macOS testing --- .github/workflows/testing-macos.yml | 46 ++++++++++++++++++----------- .pre-commit-config.yaml | 2 +- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index 2ba8105f230a..0d638129aef3 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -67,14 +67,15 @@ jobs: # do, since that's a 3x cost multiplier on the most expensive # runner tier). uv_group: [ "ci-llvm-main" ] - # x86-64 (macos-26-intel) is a follow-up: needs the runner label's - # availability verified, plus the x86-64-osx/-sse41 correctness-only - # passes and ENABLE_APPS_HANNK=OFF (no tflite on x86 macOS). - runner: [ "macos-26" ] + runner: [ "macos-26", "macos-26-intel" ] include: - runner: macos-26 arch: arm-64 python: cpython-3.10.20-macos-aarch64-none + - runner: macos-26-intel + arch: x86-64 + # uv doesn't provide macos-x86_64 builds; use a preinstalled one. + python: "3.10" steps: - uses: actions/checkout@v7 @@ -109,18 +110,12 @@ jobs: cmake -S . -B build -DHalide_TARGET=host cmake --build build --target install ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ - -LE "performance|autoschedulers" -j "$(sysctl -n hw.logicalcpu)" \ + -LE "performance|autoschedulers|fuzz" -j "$(sysctl -n hw.logicalcpu)" \ -E tutorial_lesson_19 ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ -L "performance|autoschedulers" --repeat until-pass:5 - # --- apps/ (host): first time apps/ is exercised via ctest in any of - # the CMake-preset GHA workflows (only the legacy Make-based - # testing-make.yml does today), so keep this non-blocking until proven - # green. --- - - name: Configure apps (host) - continue-on-error: true run: >- cmake -S apps -B apps-build -G Ninja @@ -128,25 +123,25 @@ jobs: -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install" -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" -DHalide_TARGET=host - -DENABLE_APPS_HANNK=ON + -DENABLE_APPS_HANNK=${{ matrix.arch == 'arm-64' && 'ON' || 'OFF' }} - name: Build apps (host) - continue-on-error: true run: cmake --build apps-build - name: Test apps (host) - continue-on-error: true run: >- ctest --test-dir apps-build --build-config RelWithDebInfo --output-on-failure -LE slow_tests --timeout 3600 - name: Configure HelloiOS + if: matrix.arch == 'arm-64' run: ./setup.sh working-directory: apps/HelloiOS env: Halide_ROOT: ${{ github.workspace }}/install - name: Build HelloiOS + if: matrix.arch == 'arm-64' run: >- xcodebuild -workspace HelloiOS.xcworkspace -scheme HelloiOS @@ -155,6 +150,24 @@ jobs: build working-directory: apps/HelloiOS + # --- x86-64-osx correctness, with and without SSE4.1 --- + + - name: Test (x86-64-osx, no SSE4.1) + if: matrix.arch == 'x86-64' + run: | + cmake -S . -B build -DHalide_TARGET=x86-64-osx + cmake --build build + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L correctness -j "$(sysctl -n hw.logicalcpu)" + + - name: Test (x86-64-osx, SSE4.1) + if: matrix.arch == 'x86-64' + run: | + cmake -S . -B build -DHalide_TARGET=x86-64-osx-sse41 + cmake --build build + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ + -L correctness -j "$(sysctl -n hw.logicalcpu)" + # --- host-metal: real GPU testing on hosted Apple Silicon runners --- - name: Test (host-metal) @@ -167,7 +180,6 @@ jobs: -L "performance|autoschedulers_gpu" --repeat until-pass:5 - name: Configure apps (host-metal) - continue-on-error: true run: >- cmake -S apps -B apps-build -G Ninja @@ -175,14 +187,12 @@ jobs: -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install" -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" -DHalide_TARGET=host-metal - -DENABLE_APPS_HANNK=ON + -DENABLE_APPS_HANNK=${{ matrix.arch == 'arm-64' && 'ON' || 'OFF' }} - name: Build apps (host-metal) - continue-on-error: true run: cmake --build apps-build - name: Test apps (host-metal) - continue-on-error: true run: >- ctest --test-dir apps-build --build-config RelWithDebInfo --output-on-failure -LE slow_tests --timeout 3600 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9215f3d1e98a..975e249d9236 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,7 +25,7 @@ repos: exclude: \.patch$ - repo: https://github.com/rhysd/actionlint - rev: v1.7.11 + rev: v1.7.12 hooks: - id: actionlint From b2c06ecfee7db2378545ee162419c93500b07da6 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 23 Jul 2026 01:12:33 -0400 Subject: [PATCH 3/5] Fix x86-64 macOS test failures from duplicate wabt/libjpeg installs --- .github/workflows/testing-macos.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index 0d638129aef3..997a9f4130aa 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -83,7 +83,20 @@ jobs: - uses: astral-sh/setup-uv@v7 - name: Install wasm toolchain - run: brew install emscripten wabt + run: brew install emscripten + + # AppleClang on Intel unconditionally injects /usr/local/include and + # /usr/local/lib into every compile/link, below CMake's control. + # Homebrew's jpeg-turbo (built with -DWITH_JPEG8=1, i.e. reports + # JPEG_LIB_VERSION 80) is preinstalled there on this runner image and + # collides with vcpkg's own libjpeg-turbo (version 62), producing + # "Wrong JPEG library version: library is 62, caller expects 80" at + # runtime. Remove it so vcpkg's copy is the only one AppleClang can see. + - name: Remove Homebrew libjpeg-turbo + if: matrix.arch == 'x86-64' + run: | + brew uninstall --ignore-dependencies --force jpeg-turbo || true + brew uninstall --ignore-dependencies --force jpeg || true - name: Sync CI environment run: | From 7fe7faa1dd5aa5828f7f0504e695e359295f8196 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 23 Jul 2026 11:04:12 -0400 Subject: [PATCH 4/5] Tame Metal GPU hangs on x86-64 by narrowing scope and retrying --- .github/workflows/testing-macos.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index 997a9f4130aa..ba3c6e8f5dd1 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -187,10 +187,21 @@ jobs: run: | cmake -S . -B build -DHalide_TARGET=host-metal cmake --build build --target install + + JOBS="$(sysctl -n hw.logicalcpu)" + RETRY_FLAGS=() + if [ "${{ matrix.arch }}" = "x86-64" ]; then + # This runner's GPU is too weak to handle the GPU tests at full + # CPU parallelism -- the driver aborts some command buffers with + # a hang error. Cut parallelism and retry. + JOBS=2 + RETRY_FLAGS=(--repeat until-pass:5) + fi + ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ - -L "correctness|generator" -j "$(sysctl -n hw.logicalcpu)" + -L "correctness|generator" -R "gpu|metal" -j "$JOBS" "${RETRY_FLAGS[@]}" ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ - -L "performance|autoschedulers_gpu" --repeat until-pass:5 + -L "performance|autoschedulers_gpu" -R "gpu|metal" --repeat until-pass:5 - name: Configure apps (host-metal) run: >- From 3d9442a8a56eefeb7e79798dfd2364f2dd3fc7e0 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 23 Jul 2026 13:23:45 -0400 Subject: [PATCH 5/5] Trim unreachable/unstable x86-64 macOS coverage: no-SSE4.1 and host-metal --- .github/workflows/testing-macos.yml | 37 +++++++++++------------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/.github/workflows/testing-macos.yml b/.github/workflows/testing-macos.yml index ba3c6e8f5dd1..f95a506db760 100644 --- a/.github/workflows/testing-macos.yml +++ b/.github/workflows/testing-macos.yml @@ -163,15 +163,9 @@ jobs: build working-directory: apps/HelloiOS - # --- x86-64-osx correctness, with and without SSE4.1 --- - - - name: Test (x86-64-osx, no SSE4.1) - if: matrix.arch == 'x86-64' - run: | - cmake -S . -B build -DHalide_TARGET=x86-64-osx - cmake --build build - ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ - -L correctness -j "$(sysctl -n hw.logicalcpu)" + # --- x86-64-osx correctness. No no-SSE4.1 variant: no real Intel Mac + # lacks SSE4.1, and that hypothetical baseline is already exercised by + # Linux/Windows CI, where it's an actually reachable target. --- - name: Test (x86-64-osx, SSE4.1) if: matrix.arch == 'x86-64' @@ -181,29 +175,24 @@ jobs: ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ -L correctness -j "$(sysctl -n hw.logicalcpu)" - # --- host-metal: real GPU testing on hosted Apple Silicon runners --- + # --- host-metal: real GPU testing on hosted Apple Silicon runners. + # arm-64 only -- GitHub's Intel macOS runners have a GPU too weak to + # sustain this workload; once it hangs once, the driver cascades into + # rejecting further submissions for the rest of the job, so reduced + # concurrency and retries don't help. --- - name: Test (host-metal) + if: matrix.arch == 'arm-64' run: | cmake -S . -B build -DHalide_TARGET=host-metal cmake --build build --target install - - JOBS="$(sysctl -n hw.logicalcpu)" - RETRY_FLAGS=() - if [ "${{ matrix.arch }}" = "x86-64" ]; then - # This runner's GPU is too weak to handle the GPU tests at full - # CPU parallelism -- the driver aborts some command buffers with - # a hang error. Cut parallelism and retry. - JOBS=2 - RETRY_FLAGS=(--repeat until-pass:5) - fi - ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ - -L "correctness|generator" -R "gpu|metal" -j "$JOBS" "${RETRY_FLAGS[@]}" + -L "correctness|generator" -R "gpu|metal" -j "$(sysctl -n hw.logicalcpu)" ctest --test-dir build --build-config RelWithDebInfo --output-on-failure \ -L "performance|autoschedulers_gpu" -R "gpu|metal" --repeat until-pass:5 - name: Configure apps (host-metal) + if: matrix.arch == 'arm-64' run: >- cmake -S apps -B apps-build -G Ninja @@ -211,12 +200,14 @@ jobs: -DCMAKE_PREFIX_PATH="${{ github.workspace }}/install" -DCMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" -DHalide_TARGET=host-metal - -DENABLE_APPS_HANNK=${{ matrix.arch == 'arm-64' && 'ON' || 'OFF' }} + -DENABLE_APPS_HANNK=ON - name: Build apps (host-metal) + if: matrix.arch == 'arm-64' run: cmake --build apps-build - name: Test apps (host-metal) + if: matrix.arch == 'arm-64' run: >- ctest --test-dir apps-build --build-config RelWithDebInfo --output-on-failure -LE slow_tests --timeout 3600