Skip to content

[multi-gpu] Phase 4: air-symmetric-alloc-to-mgpu lowering pass #1555

[multi-gpu] Phase 4: air-symmetric-alloc-to-mgpu lowering pass

[multi-gpu] Phase 4: air-symmetric-alloc-to-mgpu lowering pass #1555

Workflow file for this run

# 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 }}
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"
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
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' }}
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 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' }}