name: Build MacOS

on:
  workflow_call:
    inputs:
      matrix:
        required: true
        type: string

jobs:
  build-macos:
    runs-on: ${{ matrix.runner }}
    strategy:
      matrix:
        runner: ${{ fromJson(inputs.matrix) }}
    timeout-minutes: 60
    env:
      RUNNER_TYPE: ${{ matrix.runner[0] }}
      TRITON_BUILD_WITH_CLANG_LLD: "TRUE"
    name: Build MacOS
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: "true"
      - name: Install brew dependencies
        run: |
          brew update
          brew install ccache llvm@19 lld coreutils
      - name: Compute cache keys
        id: cache-key
        run: |
          llvm_file="cmake/llvm-hash.txt"
          nvidia_file="cmake/nvidia-toolchain-version.json"
          json_file="cmake/json-version.txt"

          # Check if files exist before proceeding
          if [[ ! -f "$llvm_file" || ! -f "$nvidia_file" || ! -f "$json_file" ]]; then
            echo "Error: Required dependency files are missing."
            exit 1
          fi

          # Process the files if they exist
          echo "llvm=$(cat $llvm_file | cut -c 1-8)" >> $GITHUB_OUTPUT
          echo "nvidia=$(sha256sum $nvidia_file | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
          echo "json=$(cat $json_file)" >> $GITHUB_OUTPUT
          echo "datetime=$(date -u -Iseconds)" >> $GITHUB_OUTPUT
        shell: bash
      - name: Cache build dependencies
        uses: actions/cache@v4
        with:
          # Note that we cannot use environment variables here given there is
          # no shell to interpret them in the paths.
          path: |
            ~/.triton/llvm
            ~/.triton/nvidia
            ~/.triton/json
          key: ${{ runner.os }}-${{ runner.arch }}-llvm-${{ steps.cache-key.outputs.llvm }}-nvidia-${{ steps.cache-key.outputs.nvidia }}-json-${{ steps.cache-key.outputs.json }}
      - # Cache ~/.cache/ccache to speed up compilation.
        #
        # On branch `main` we always start from an empty cache, i.e. we skip the
        # "restore" step.  This is to prevent the caches from accumulating stale
        # files over time.
        name: Restore cache of ccache and Triton compilation artifacts
        id: restore-build-cache
        if: github.ref != 'refs/heads/main'
        uses: actions/cache/restore@v4
        with:
          path: |
            ~/.ccache
          # Restore the most recent cache entry.
          restore-keys: |
            triton-artifacts-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_TYPE }}-llvm-${{ steps.cache-key.outputs.llvm }}-
            triton-artifacts-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_TYPE }}-
          # We expect this cache key never to hit and for us to fall back
          # unconditionally to the restore-key, so it doesn't actually matter
          # what we put here (so long as it doesn't hit an existing key).
          key: triton-artifacts-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_TYPE }}-llvm-${{ steps.cache-key.outputs.llvm }}-${{ steps.cache-key.outputs.datetime }}
      - name: Inspect cache directories
        run: |
          mkdir -p ~/.triton
          du -h -d 1 ~/.triton

          mkdir -p ~/.ccache
          du -h -d 1 ~/.ccache
      - name: Update PATH
        run: |
          echo "$HOME/.local/bin" >> $GITHUB_PATH
          echo "/opt/homebrew/opt/llvm/bin" >> $GITHUB_PATH
      - name: Create venv
        run: |
          python3 -m venv ~/.venv
          source ~/.venv/bin/activate
          python3 -m pip install --upgrade pip
      - name: Install Triton
        env:
          TRITON_BUILD_WITH_O1: "true"
          # macos-latest has 3 vcpus and 7GB DRAM, to save memory we limit the number of jobs to 3
          # https://docs.github.com/en/actions/reference/github-hosted-runners-reference#standard-github-hosted-runners-for-public-repositories
          MAX_JOBS: 3
          # Add elapsed time in seconds to ninja status to monitor where build stalls
          NINJA_STATUS: "[%f/%t, %es elapsed] "
        run: |
          source ~/.venv/bin/activate
          echo "PATH is '$PATH'"
          ccache --zero-stats
          export PATH="/opt/homebrew/opt/llvm@19/bin:$PATH"
          export CC="/opt/homebrew/opt/llvm@19/bin/clang"
          export CXX="/opt/homebrew/opt/llvm@19/bin/clang++"
          export CXXFLAGS="-stdlib=libc++"
          export LDFLAGS="-L/opt/homebrew/opt/llvm@19/lib"
          which clang++
          clang++ --version
          make dev-install
      - name: CCache Stats
        run: ccache --print-stats
      - name: Inspect cache directories
        run: |
          mkdir -p ~/.triton
          du -h -d 1 ~/.triton

          mkdir -p ~/.ccache
          du -h -d 1 ~/.ccache
      - # If we're on branch `main`, save the ccache Triton compilation artifacts
        # to the cache so they can be used by other (non-main) CI runs.
        #
        # (It wouldn't be a problem to save the cache on every run, because github
        # evicts cache entries LRU, but maybe this saves a bit of time in CI.)
        name: Save ccache and Triton compilation artifacts to cache
        if: github.ref == 'refs/heads/main'
        uses: actions/cache/save@v4
        with:
          path: |
            ~/.ccache
          key: triton-artifacts-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_TYPE }}-llvm-${{ steps.cache-key.outputs.llvm }}-${{ steps.cache-key.outputs.datetime }}