Build mlir-air Wheels #55
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
| # Copyright (C) 2025, Advanced Micro Devices, Inc. | |
| # SPDX-License-Identifier: MIT | |
| name: Build mlir-air Wheels | |
| on: | |
| pull_request: | |
| merge_group: | |
| workflow_dispatch: | |
| inputs: | |
| AIR_COMMIT: | |
| description: 'AIR commit to build' | |
| type: string | |
| required: false | |
| default: '' | |
| push: | |
| tags: | |
| - 'v*.*.*' | |
| schedule: | |
| - cron: '0 4 * * *' # Daily at 4 AM | |
| defaults: | |
| run: | |
| shell: bash | |
| concurrency: | |
| group: ci-build-air-wheels-${{ github.event.number || github.sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| check-new-commits: | |
| name: Check for new commits since last release | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'schedule' | |
| outputs: | |
| has_new_commits: ${{ steps.check.outputs.has_new_commits }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Check if HEAD differs from last released wheel | |
| id: check | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| CURRENT_SHORT=$(git rev-parse --short=7 HEAD) | |
| echo "Current HEAD: $CURRENT_SHORT" | |
| # Returns "true" if the given release tag is stale (hash mismatch or missing). | |
| check_tag() { | |
| local TAG="$1" | |
| local LAST_WHEEL | |
| LAST_WHEEL=$(gh api "repos/${{ github.repository }}/releases/tags/${TAG}" \ | |
| --jq '.assets | sort_by(.created_at) | reverse | map(select(.name | startswith("mlir_air")) | .name) | .[0] // empty' \ | |
| 2>/dev/null || echo "") | |
| if [ -z "$LAST_WHEEL" ]; then | |
| echo " No wheel found for ${TAG}, needs build." >&2 | |
| echo "true" | |
| return | |
| fi | |
| # Extract short hash from wheel name: mlir_air-0.0.1.DATETIME+HASH-... | |
| # No-RTTI wheels have _no_rtti after the hash, so match any char after the 7 hex digits. | |
| local LAST_HASH | |
| LAST_HASH=$(echo "$LAST_WHEEL" | sed -n 's/.*+\([a-f0-9]\{7\}\)[^a-f0-9].*/\1/p') | |
| echo " ${TAG}: latest wheel hash=${LAST_HASH:-<none>}" >&2 | |
| if [ -z "$LAST_HASH" ] || [ "$CURRENT_SHORT" != "$LAST_HASH" ]; then | |
| echo "true" | |
| else | |
| echo "false" | |
| fi | |
| } | |
| # Check both RTTI and no-RTTI release tags; build if either is stale. | |
| RTTI_STALE=$(check_tag "latest-air-wheels") | |
| NO_RTTI_STALE=$(check_tag "latest-air-wheels-no-rtti") | |
| if [ "$RTTI_STALE" = "true" ] || [ "$NO_RTTI_STALE" = "true" ]; then | |
| echo "One or both releases are stale. Building." | |
| echo "has_new_commits=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Both releases are up to date. Skipping build." | |
| echo "has_new_commits=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| get-air-project-commit: | |
| name: Get canonical AIR project commit and timestamp | |
| runs-on: ubuntu-latest | |
| needs: check-new-commits | |
| if: always() && (github.event_name != 'schedule' || needs.check-new-commits.outputs.has_new_commits == 'true') | |
| outputs: | |
| AIR_PROJECT_COMMIT: ${{ steps.get_commit.outputs.AIR_PROJECT_COMMIT }} | |
| DATETIME: ${{ steps.get_commit.outputs.DATETIME }} | |
| MLIR_AIE_VERSION: ${{ steps.get_commit.outputs.MLIR_AIE_VERSION }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Get AIR project commit and timestamp | |
| id: get_commit | |
| run: | | |
| if [ x"${{ inputs.AIR_COMMIT }}" == x"" ]; then | |
| AIR_PROJECT_COMMIT=$(git rev-parse --short=7 HEAD) | |
| else | |
| AIR_PROJECT_COMMIT="${{ inputs.AIR_COMMIT }}" | |
| AIR_PROJECT_COMMIT="${AIR_PROJECT_COMMIT:0:7}" | |
| fi | |
| echo "AIR_PROJECT_COMMIT=${AIR_PROJECT_COMMIT}" | tee -a "$GITHUB_OUTPUT" | |
| DATETIME=$(date +"%Y%m%d%H") | |
| echo "DATETIME=${DATETIME}" | tee -a "$GITHUB_OUTPUT" | |
| # The pinned mlir-aie wheel version that this AIR commit was built and | |
| # tested against. Surfaced into the release body so users install the | |
| # matching mlir-aie wheel rather than guessing latest. | |
| MLIR_AIE_VERSION=$(utils/clone-mlir-aie.sh --get-wheel-version) | |
| echo "MLIR_AIE_VERSION=${MLIR_AIE_VERSION}" | tee -a "$GITHUB_OUTPUT" | |
| build-repo: | |
| name: Build and upload mlir_air wheels | |
| needs: [check-new-commits, get-air-project-commit] | |
| if: always() && (github.event_name != 'schedule' || needs.check-new-commits.outputs.has_new_commits == 'true') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| id-token: write | |
| contents: write | |
| packages: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - python_version: "3.10" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.10" | |
| ENABLE_RTTI: OFF | |
| - python_version: "3.11" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.11" | |
| ENABLE_RTTI: OFF | |
| - python_version: "3.12" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.12" | |
| ENABLE_RTTI: OFF | |
| - python_version: "3.13" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.13" | |
| ENABLE_RTTI: OFF | |
| - python_version: "3.14" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.14" | |
| ENABLE_RTTI: OFF | |
| steps: | |
| - name: Free disk space | |
| uses: descriptinc/free-disk-space@main | |
| with: | |
| tool-cache: true | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| swap-storage: false | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: "true" | |
| - uses: uraimo/run-on-arch-action@v2.7.0 | |
| name: Build mlir-air | |
| id: runcmd | |
| with: | |
| distro: none | |
| arch: none | |
| base_image: quay.io/pypa/manylinux_2_34_x86_64:latest | |
| githubToken: ${{ github.token }} | |
| env: | | |
| AIR_WHEEL_VERSION: ${{ (github.ref_type == 'tag' && startsWith(github.ref_name, 'v')) && github.ref_name || '""' }} | |
| run: | | |
| git config --global --add safe.directory $PWD | |
| AIR_VERSION=$(git rev-parse --short HEAD) | |
| echo "Building mlir-air version $AIR_VERSION" | |
| if ! command -v python${{ matrix.python_version }} &> /dev/null; then | |
| echo "Python ${{ matrix.python_version }} not found, installing..." | |
| yum update -y | |
| yum install -y yum-utils | |
| yum install -y python${{ matrix.python_version }} python${{ matrix.python_version }}-devel | |
| fi | |
| yum install -y ninja-build clang lld zip unzip binutils | |
| python${{ matrix.python_version }} -m venv ${{ github.workspace }}/air-venv | |
| source ${{ github.workspace }}/air-venv/bin/activate | |
| pip install -r utils/requirements.txt | |
| pip install -r utils/requirements_dev.txt | |
| export ENABLE_RTTI=${{ matrix.ENABLE_RTTI }} | |
| NO_RTTI="" | |
| NO_RTTI_UNDERSCORE="" | |
| NO_RTTI_DOT="" | |
| if [ x"$ENABLE_RTTI" == x"OFF" ]; then | |
| NO_RTTI="-no-rtti" | |
| NO_RTTI_UNDERSCORE="_no_rtti" | |
| NO_RTTI_DOT=".no.rtti" | |
| MLIR_AIE_WHEELS_URL="https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-no-rtti" | |
| else | |
| MLIR_AIE_WHEELS_URL="https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-3/" | |
| fi | |
| VERSION=$(utils/clone-llvm.sh --get-wheel-version) | |
| pip -q download --no-deps "mlir$NO_RTTI==$VERSION" \ | |
| -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/mlir-distro | |
| unzip -q mlir*.whl | |
| find mlir$NO_RTTI_UNDERSCORE -exec touch -a -m -t 201108231405.14 {} \; | |
| export MLIR_INSTALL_ABS_PATH=$PWD/mlir$NO_RTTI_UNDERSCORE | |
| export MLIR_AIE_VERSION=$(utils/clone-mlir-aie.sh --get-wheel-version) | |
| pip -q download --no-deps --platform manylinux_2_35_x86_64 "mlir_aie==${MLIR_AIE_VERSION}${NO_RTTI_DOT}" \ | |
| -f "$MLIR_AIE_WHEELS_URL" | |
| unzip -q mlir_aie*.whl | |
| export MLIR_AIE_INSTALL_PATH=$PWD/mlir_aie | |
| export MLIR_AIR_SOURCE_DIR=$PWD | |
| export WHEELHOUSE_DIR=$PWD/wheelhouse | |
| export AIR_PROJECT_COMMIT=${{ needs.get-air-project-commit.outputs.AIR_PROJECT_COMMIT }} | |
| export DATETIME=${{ needs.get-air-project-commit.outputs.DATETIME }} | |
| rm -rf $WHEELHOUSE_DIR/mlir_air*.whl | |
| rm -rf $WHEELHOUSE_DIR/repaired_wheel/* | |
| pushd utils/mlir_air_wheels | |
| pip install setuptools wheel auditwheel patchelf importlib_metadata | |
| CIBW_ARCHS=x86_64 pip wheel . -v -w $WHEELHOUSE_DIR --no-build-isolation | |
| popd | |
| auditwheel repair -w $WHEELHOUSE_DIR/repaired_wheel $WHEELHOUSE_DIR/mlir_air*.whl --plat manylinux_2_35_x86_64 --exclude libmlir_async_runtime.so --exclude libmlir_c_runner_utils.so --exclude libmlir_float16_utils.so --exclude libmlir_runner_utils.so --exclude libmlir_apfloat_wrappers.so | |
| - name: Upload mlir_air | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| path: wheelhouse/mlir_air*whl | |
| name: mlir_air_rtti_${{ matrix.ENABLE_RTTI }}-${{ matrix.python_version }} | |
| - name: Release | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'schedule' || | |
| (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) | |
| uses: ncipollo/release-action@v1.12.0 | |
| with: | |
| artifacts: wheelhouse/mlir_air*whl | |
| token: "${{ secrets.GITHUB_TOKEN }}" | |
| tag: ${{ github.event_name == 'push' && github.ref_name || (matrix.ENABLE_RTTI == 'ON' && 'latest-air-wheels' || 'latest-air-wheels-no-rtti') }} | |
| name: ${{ github.event_name == 'push' && github.ref_name || (matrix.ENABLE_RTTI == 'ON' && 'latest-air-wheels' || 'latest-air-wheels-no-rtti') }} | |
| allowUpdates: true | |
| replacesArtifacts: true | |
| makeLatest: ${{ github.event_name == 'push' }} | |
| # Skip body on versioned tag pushes (v*.*.*) so those releases can carry | |
| # human-written or auto-generated notes; only populate body for the | |
| # rolling latest-* tags. | |
| omitBody: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }} | |
| body: | | |
| ## MLIR-AIR Wheels (${{ matrix.ENABLE_RTTI == 'ON' && 'RTTI' || 'no-RTTI' }}) | |
| **Latest commit:** `${{ needs.get-air-project-commit.outputs.AIR_PROJECT_COMMIT }}` | |
| **Pinned mlir_aie:** `${{ needs.get-air-project-commit.outputs.MLIR_AIE_VERSION }}${{ matrix.ENABLE_RTTI == 'ON' && '' || '.no.rtti' }}` | |
| **Platforms:** Linux x86_64 (Python 3.10–3.14), Windows AMD64 (Python 3.10–3.12) | |
| ### Installation | |
| AIR supports multiple backends (AIE, GPU, VCK5000); backend dependencies are exposed as pip extras. For the AIE backend, the `[aie]` extra pulls the matching pinned `mlir_aie` and `llvm-aie` from the additional `--find-links` pages: | |
| ```bash | |
| pip install 'mlir_air[aie]' \ | |
| -f https://github.com/Xilinx/mlir-air/releases/expanded_assets/${{ matrix.ENABLE_RTTI == 'ON' && 'latest-air-wheels' || 'latest-air-wheels-no-rtti' }} \ | |
| -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/${{ matrix.ENABLE_RTTI == 'ON' && 'latest-wheels-3' || 'latest-wheels-no-rtti' }} \ | |
| -f https://github.com/Xilinx/llvm-aie/releases/expanded_assets/nightly | |
| ``` | |
| Drop the `[aie]` extra to install AIR core only (e.g. when bringing your own backend). | |
| ### RTTI / no-RTTI Variants | |
| Both RTTI-enabled and RTTI-disabled wheels are released for downstream integration convenience: | |
| - [`latest-air-wheels`](https://github.com/Xilinx/mlir-air/releases/tag/latest-air-wheels) — RTTI **on**. Default; use this for standalone development. | |
| - [`latest-air-wheels-no-rtti`](https://github.com/Xilinx/mlir-air/releases/tag/latest-air-wheels-no-rtti) — RTTI **off**. For integrating MLIR-AIR into a downstream project whose LLVM is built with `-DLLVM_ENABLE_RTTI=OFF`. | |
| When mixing wheels into a downstream build, all three of `mlir`, `mlir_aie`, and `mlir_air` must agree on RTTI. | |
| Full setup guide: [docs/buildingRyzenLin.md](https://github.com/Xilinx/mlir-air/blob/main/docs/buildingRyzenLin.md#install-prebuilt-wheels-recommended) | |
| build-windows: | |
| name: Build and upload mlir_air wheels (Windows) | |
| needs: [check-new-commits, get-air-project-commit] | |
| if: always() && (github.event_name != 'schedule' || needs.check-new-commits.outputs.has_new_commits == 'true') | |
| runs-on: windows-2022 | |
| permissions: | |
| id-token: write | |
| contents: write | |
| packages: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - python_version: "3.10" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.10" | |
| ENABLE_RTTI: OFF | |
| - python_version: "3.11" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.11" | |
| ENABLE_RTTI: OFF | |
| - python_version: "3.12" | |
| ENABLE_RTTI: ON | |
| - python_version: "3.12" | |
| ENABLE_RTTI: OFF | |
| # Python 3.13+ requires numpy>=2.0 which is incompatible with | |
| # our numpy<2.0 pin. Expand once the pin is lifted. | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: "true" | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python_version }} | |
| - uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: x64 | |
| - name: Install Python packages | |
| shell: bash | |
| run: | | |
| pip install -r utils/requirements.txt | |
| pip install -r utils/requirements_dev.txt | |
| pip install setuptools wheel delvewheel importlib_metadata "ninja!=1.13.0" | |
| - name: Get MLIR | |
| shell: bash | |
| run: | | |
| NO_RTTI="" NO_RTTI_UNDERSCORE="" | |
| if [ x"${{ matrix.ENABLE_RTTI }}" == x"OFF" ]; then | |
| NO_RTTI="-no-rtti" | |
| NO_RTTI_UNDERSCORE="_no_rtti" | |
| fi | |
| VERSION=$(utils/clone-llvm.sh --get-wheel-version) | |
| pip -q download --no-deps "mlir${NO_RTTI}==${VERSION}" \ | |
| -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/mlir-distro | |
| # Extract to a short path to keep linker .rsp file paths under | |
| # MSVC limits. Junction links don't help because CMake resolves | |
| # them to the real path internally. | |
| rm -rf /c/tmp/airwhls/m | |
| python -m zipfile -e mlir*.whl /c/tmp/airwhls | |
| mv "/c/tmp/airwhls/mlir${NO_RTTI_UNDERSCORE}" /c/tmp/airwhls/m | |
| find /c/tmp/airwhls/m -exec touch -a -m -t 201108231405.14 {} \; | |
| - name: Get mlir-aie | |
| shell: bash | |
| run: | | |
| NO_RTTI_DOT="" | |
| if [ x"${{ matrix.ENABLE_RTTI }}" == x"OFF" ]; then | |
| NO_RTTI_DOT=".no.rtti" | |
| MLIR_AIE_WHEELS_URL="https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-no-rtti" | |
| else | |
| MLIR_AIE_WHEELS_URL="https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-3/" | |
| fi | |
| MLIR_AIE_VERSION=$(utils/clone-mlir-aie.sh --get-wheel-version) | |
| pip -q download --no-deps --platform win_amd64 \ | |
| "mlir_aie==${MLIR_AIE_VERSION}${NO_RTTI_DOT}" \ | |
| -f "$MLIR_AIE_WHEELS_URL" | |
| # Extract to a short path alongside MLIR | |
| MLIR_AIE_EXTRACT=/c/tmp/airwhls/a | |
| rm -rf "$MLIR_AIE_EXTRACT" | |
| mkdir -p /c/tmp/airwhls | |
| python -m zipfile -e mlir_aie*.whl /c/tmp/airwhls | |
| mv /c/tmp/airwhls/mlir_aie "$MLIR_AIE_EXTRACT" | |
| - name: Build wheel | |
| shell: bash | |
| env: | |
| AIR_WHEEL_VERSION: ${{ (github.ref_type == 'tag' && startsWith(github.ref_name, 'v')) && github.ref_name || '' }} | |
| run: | | |
| set -euo pipefail | |
| ROOT=$(python -c "import os; print(os.getcwd().replace('\\\\', '/'))") | |
| export MLIR_INSTALL_ABS_PATH="C:/tmp/airwhls/m" | |
| export MLIR_AIE_INSTALL_PATH="C:/tmp/airwhls/a" | |
| export MLIR_AIR_SOURCE_DIR="${ROOT}" | |
| export ENABLE_RTTI=${{ matrix.ENABLE_RTTI }} | |
| export CIBW_ARCHS=AMD64 | |
| export AIR_PROJECT_COMMIT=${{ needs.get-air-project-commit.outputs.AIR_PROJECT_COMMIT }} | |
| export DATETIME=${{ needs.get-air-project-commit.outputs.DATETIME }} | |
| export MLIR_AIE_VERSION=${{ needs.get-air-project-commit.outputs.MLIR_AIE_VERSION }} | |
| export WHEELHOUSE_DIR="${ROOT}/wheelhouse" | |
| mkdir -p "$WHEELHOUSE_DIR" | |
| rm -rf "$WHEELHOUSE_DIR"/mlir_air*.whl | |
| rm -rf "$WHEELHOUSE_DIR"/repaired_wheel/* | |
| ninja --version | |
| pushd utils/mlir_air_wheels | |
| pip wheel . -v -w "$WHEELHOUSE_DIR" --no-build-isolation | |
| popd | |
| - name: Repair wheel | |
| shell: bash | |
| run: | | |
| python -m delvewheel repair \ | |
| --ignore-existing --analyze-existing-exes \ | |
| -w wheelhouse/repaired_wheel \ | |
| wheelhouse/mlir_air*.whl | |
| - name: Upload mlir_air | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| path: wheelhouse/repaired_wheel/mlir_air*whl | |
| name: mlir_air_windows_rtti_${{ matrix.ENABLE_RTTI }}-${{ matrix.python_version }} | |
| - name: Release | |
| if: | | |
| github.event_name == 'workflow_dispatch' || | |
| github.event_name == 'schedule' || | |
| (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) | |
| uses: ncipollo/release-action@v1.12.0 | |
| with: | |
| artifacts: wheelhouse/repaired_wheel/mlir_air*whl | |
| token: "${{ secrets.GITHUB_TOKEN }}" | |
| tag: ${{ github.event_name == 'push' && github.ref_name || (matrix.ENABLE_RTTI == 'ON' && 'latest-air-wheels' || 'latest-air-wheels-no-rtti') }} | |
| name: ${{ github.event_name == 'push' && github.ref_name || (matrix.ENABLE_RTTI == 'ON' && 'latest-air-wheels' || 'latest-air-wheels-no-rtti') }} | |
| allowUpdates: true | |
| replacesArtifacts: true | |
| makeLatest: ${{ github.event_name == 'push' }} | |
| # Skip body on versioned tag pushes (v*.*.*) so those releases can carry | |
| # human-written or auto-generated notes; only populate body for the | |
| # rolling latest-* tags. | |
| omitBody: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }} | |
| body: | | |
| ## MLIR-AIR Wheels (${{ matrix.ENABLE_RTTI == 'ON' && 'RTTI' || 'no-RTTI' }}) | |
| **Latest commit:** `${{ needs.get-air-project-commit.outputs.AIR_PROJECT_COMMIT }}` | |
| **Pinned mlir_aie:** `${{ needs.get-air-project-commit.outputs.MLIR_AIE_VERSION }}${{ matrix.ENABLE_RTTI == 'ON' && '' || '.no.rtti' }}` | |
| **Platforms:** Linux x86_64 (Python 3.10–3.14), Windows AMD64 (Python 3.10–3.12) | |
| ### Installation | |
| AIR supports multiple backends (AIE, GPU, VCK5000); backend dependencies are exposed as pip extras. For the AIE backend, the `[aie]` extra pulls the matching pinned `mlir_aie` and `llvm-aie` from the additional `--find-links` pages: | |
| ```bash | |
| pip install 'mlir_air[aie]' \ | |
| -f https://github.com/Xilinx/mlir-air/releases/expanded_assets/${{ matrix.ENABLE_RTTI == 'ON' && 'latest-air-wheels' || 'latest-air-wheels-no-rtti' }} \ | |
| -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/${{ matrix.ENABLE_RTTI == 'ON' && 'latest-wheels-3' || 'latest-wheels-no-rtti' }} \ | |
| -f https://github.com/Xilinx/llvm-aie/releases/expanded_assets/nightly | |
| ``` | |
| Drop the `[aie]` extra to install AIR core only (e.g. when bringing your own backend). | |
| ### RTTI / no-RTTI Variants | |
| Both RTTI-enabled and RTTI-disabled wheels are released for downstream integration convenience: | |
| - [`latest-air-wheels`](https://github.com/Xilinx/mlir-air/releases/tag/latest-air-wheels) — RTTI **on**. Default; use this for standalone development. | |
| - [`latest-air-wheels-no-rtti`](https://github.com/Xilinx/mlir-air/releases/tag/latest-air-wheels-no-rtti) — RTTI **off**. For integrating MLIR-AIR into a downstream project whose LLVM is built with `-DLLVM_ENABLE_RTTI=OFF`. | |
| When mixing wheels into a downstream build, all three of `mlir`, `mlir_aie`, and `mlir_air` must agree on RTTI. | |
| Full setup guide: [docs/buildingRyzenLin.md](https://github.com/Xilinx/mlir-air/blob/main/docs/buildingRyzenLin.md#install-prebuilt-wheels-recommended) |