name: CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref && github.ref || github.run_id }}
  cancel-in-progress: true

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        libraries: [shared, static]

    runs-on: ${{ matrix.os }}

    steps:
    - name: Clone
      uses: actions/checkout@v6

    - name: Dependencies for Ubuntu
      if: matrix.os == 'ubuntu-latest'
      run: |
        sudo apt-get update
        sudo apt-get install llvm

    - name: Add msbuild to PATH
      if: matrix.os == 'windows-latest'
      uses: microsoft/setup-msbuild@v2

    - name: Create Build Environment
      run: mkdir build

    - name: Configure CMake
      working-directory: ./build
      run: cmake ..
        ${{ contains(matrix.os, 'windows') && '-A x64' || '-G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++' }}
        ${{ matrix.libraries == 'static' && '-DBUILD_SHARED_LIBS=OFF' || '-DBUILD_SHARED_LIBS=ON' }}
        -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/installed
        -DGGML_METAL=OFF

    - name: Build
      working-directory: ./build
      run: cmake --build . ${{ contains(matrix.os, 'windows') && '--config Release' || '' }}

    - name: Test
      working-directory: ./build
      run: ctest --verbose --timeout 900 ${{ contains(matrix.os, 'windows') && '--build-config Release' || '' }}

    - name: Install
      working-directory: ./build
      run: cmake --build . --target install ${{ contains(matrix.os, 'windows') && '--config Release' || '' }}

    - name: Test CMake config
      run: |
        mkdir test-cmake
        cmake -S examples/test-cmake -B test-cmake -DCMAKE_PREFIX_PATH=${{ github.workspace }}/installed ${{ contains(matrix.os, 'windows') && '-A x64' || '-G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++' }}
        cmake --build test-cmake ${{ contains(matrix.os, 'windows') && '--config Release' || '' }}

# TODO: simplify the following workflows using a matrix
  ggml-ci-x64-cpu-low-perf:
    runs-on: ubuntu-22.04

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: ccache
        uses: ggml-org/ccache-action@v1.2.16
        with:
          key: ggml-ci-x64-cpu-low-perf
          evict-old-files: 1d

      - name: Dependencies
        id: depends
        run: |
          sudo apt-get update
          sudo apt-get install build-essential libcurl4-openssl-dev

      - name: Test
        id: ggml-ci
        run: |
          LLAMA_ARG_THREADS=$(nproc) GG_BUILD_LOW_PERF=1 bash ./ci/run.sh ./tmp/results ./tmp/mnt

  ggml-ci-arm64-cpu-low-perf:
    runs-on: ubuntu-22.04-arm

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: ccache
        uses: ggml-org/ccache-action@v1.2.16
        with:
          key: ggml-ci-arm64-cpu-low-perf
          evict-old-files: 1d

      - name: Dependencies
        id: depends
        run: |
          sudo apt-get update
          sudo apt-get install build-essential libcurl4-openssl-dev

      - name: Test
        id: ggml-ci
        run: |
          LLAMA_ARG_THREADS=$(nproc) GG_BUILD_LOW_PERF=1 bash ./ci/run.sh ./tmp/results ./tmp/mnt

  ggml-ci-x64-cpu-high-perf:
    runs-on: ubuntu-22.04

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: ccache
        uses: ggml-org/ccache-action@v1.2.16
        with:
          key: ggml-ci-x64-cpu-high-perf
          evict-old-files: 1d

      - name: Dependencies
        id: depends
        run: |
          sudo apt-get update
          sudo apt-get install build-essential libcurl4-openssl-dev

      - name: Test
        id: ggml-ci
        run: |
          LLAMA_ARG_THREADS=$(nproc) bash ./ci/run.sh ./tmp/results ./tmp/mnt

  ggml-ci-arm64-cpu-high-perf:
    runs-on: ubuntu-22.04-arm

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: ccache
        uses: ggml-org/ccache-action@v1.2.16
        with:
          key: ggml-ci-arm64-cpu-high-perf
          evict-old-files: 1d

      - name: Dependencies
        id: depends
        run: |
          sudo apt-get update
          sudo apt-get install build-essential libcurl4-openssl-dev

      - name: Test
        id: ggml-ci
        run: |
          LLAMA_ARG_THREADS=$(nproc) GG_BUILD_NO_SVE=1 GG_BUILD_NO_BF16=1 GG_BUILD_EXTRA_TESTS_0=1 bash ./ci/run.sh ./tmp/results ./tmp/mnt

  ggml-ci-arm64-cpu-high-perf-sve:
    runs-on: ubuntu-22.04-arm

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: ccache
        uses: ggml-org/ccache-action@v1.2.16
        with:
          key: ggml-ci-arm64-cpu-high-perf-sve
          evict-old-files: 1d

      - name: Dependencies
        id: depends
        run: |
          sudo apt-get update
          sudo apt-get install build-essential libcurl4-openssl-dev

      - name: Test
        id: ggml-ci
        run: |
          LLAMA_ARG_THREADS=$(nproc) GG_BUILD_NO_BF16=1 GG_BUILD_EXTRA_TESTS_0=1 bash ./ci/run.sh ./tmp/results ./tmp/mnt

  ggml-ci-x64-nvidia-cuda:
    runs-on: [self-hosted, Linux, X64, NVIDIA]

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: Test
        id: ggml-ci
        run: |
          nvidia-smi
          GG_BUILD_CUDA=1 bash ./ci/run.sh ~/results/ggml /mnt/ggml

  ggml-ci-x64-nvidia-vulkan-cm:
    runs-on: [self-hosted, Linux, X64, NVIDIA]

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: Test
        id: ggml-ci
        run: |
          vulkaninfo --summary
          GG_BUILD_VULKAN=1 GGML_VK_DISABLE_COOPMAT2=1 bash ./ci/run.sh ~/results/ggml /mnt/ggml

  ggml-ci-x64-nvidia-vulkan-cm2:
    runs-on: [self-hosted, Linux, X64, NVIDIA, COOPMAT2]

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: Test
        id: ggml-ci
        run: |
          vulkaninfo --summary
          GG_BUILD_VULKAN=1 bash ./ci/run.sh ~/results/ggml /mnt/ggml

  # TODO: provision AMX-compatible machine
  #ggml-ci-x64-cpu-amx:
  #  runs-on: [self-hosted, Linux, X64, CPU, AMX]

  #  steps:
  #    - name: Clone
  #      id: checkout
  #      uses: actions/checkout@v6

  #    - name: Test
  #      id: ggml-ci
  #      run: |
  #        bash ./ci/run.sh ~/results/ggml /mnt/ggml

  ggml-ci-mac-metal:
    runs-on: [self-hosted, macOS, ARM64]

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: Test
        id: ggml-ci
        run: |
          GG_BUILD_METAL=1 bash ./ci/run.sh ~/results/ggml ~/mnt/ggml

  ggml-ci-mac-vulkan:
    runs-on: [self-hosted, macOS, ARM64]

    steps:
      - name: Clone
        id: checkout
        uses: actions/checkout@v6

      - name: Test
        id: ggml-ci
        run: |
          vulkaninfo --summary
          GG_BUILD_VULKAN=1 bash ./ci/run.sh ~/results/ggml ~/mnt/ggml
