### Install system dependencies Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Install required build tools including ninja, clang, and lld. ```bash sudo apt-get install -y ninja-build clang lld unzip ``` -------------------------------- ### Verify installation Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Checks the installation by verifying the version and importing required modules. ```batch call air_env.cmd air-opt --version python -c "import air, pyxrt; print('ok')" ``` -------------------------------- ### Configure environment and run hardware examples Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Use this batch script to set up the required runtime environment, including GNU make and Git utilities, before running the Peano programming examples. ```batch @echo off call C:\dev\mlir-aie\iron_env.cmd || exit /b 1 set "MLIR_AIR_INSTALL_DIR=C:\dev\mlir-air\install" set "PATH=%MLIR_AIR_INSTALL_DIR%\bin;%PATH%" REM GNU make, plus Git's usr\bin for the sh.exe make uses as its shell. Both REM install per-user or machine-wide depending on how they were installed, so REM probe rather than assume; add your own directories if either came from REM MSYS2 or Chocolatey instead. if exist "%LOCALAPPDATA%\Microsoft\WinGet\Links\make.exe" set "PATH=%LOCALAPPDATA%\Microsoft\WinGet\Links;%PATH%" if exist "%ProgramFiles%\Git\usr\bin\sh.exe" set "PATH=%ProgramFiles%\Git\usr\bin;%PATH%" if exist "%LOCALAPPDATA%\Programs\Git\usr\bin\sh.exe" set "PATH=%LOCALAPPDATA%\Programs\Git\usr\bin;%PATH%" where make >nul 2>&1 || (echo GNU make not found -- see section 1.2. & exit /b 1) where sh >nul 2>&1 || (echo sh.exe not found; is Git for Windows installed? & exit /b 1) cd /d C:\dev\mlir-air\build ninja check-programming-examples-peano ``` -------------------------------- ### Install Dependencies Without Full MLIR-AIE Clone Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Alternative setup method using standalone CMake modules and the MLIR-AIE wheel. ```bash git clone --depth 1 https://github.com/Xilinx/cmakeModules.git C:\dev\cmakeModules pip install mlir_aie -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-4 pip install -r C:\dev\mlir-air\utils\requirements_dev.txt ``` -------------------------------- ### air.channel.get Examples Source: https://xilinx.github.io/mlir-air/dev/AIRDialect Examples showing synchronous and asynchronous channel receive operations. ```mlir // Receive a 4x4 tile into %dst from channel @chan_0 air.channel.get @chan_0(%dst[%c0, %c0][%c4, %c4][%c1, %c1]) : (memref<16x16xf32>) // Asynchronous get with dependency on %t1 %t2 = air.channel.get async [%t1] @chan_1(%dst[%c8, %c0][%c4, %c4][%c1, %c1]) : (memref<16x16xf32>) ``` -------------------------------- ### Run a specific example with lit Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Execute a single programming example using the lit test runner within the configured environment. ```bash lit -sv -j1 --filter "eltwise_add_with_l2.*peano" C:/dev/mlir-air/build/programming_examples ``` -------------------------------- ### Environment Setup Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Commands to configure the environment after building, with variants for pip-installed or source-built llvm-aie. ```bash # If you have llvm-aie (PEANO) installed via pip: source utils/env_setup.sh install-xrt/ mlir-aie/install/ $(python3 -m pip show llvm-aie | grep Location | awk '{print $2}')/llvm-aie llvm/install/ # Or if you built llvm-aie from source: source utils/env_setup.sh install-xrt/ mlir-aie/install/ /path/to/llvm-aie/install llvm/install/ ``` -------------------------------- ### Setup Python virtual environment Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Configure the Python environment with necessary packages. ```bash source utils/setup_python_packages.sh ``` -------------------------------- ### Run Matrix-Scalar Addition Example on NPU2 Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Executes the matrix-scalar addition example using the ELF output format supported on NPU2 devices. ```bash cd programming_examples\matrix_scalar_add\single_core_dma mkdir build_peano cd build_peano python ..\single_core_dma.py --output-format elf ``` -------------------------------- ### Define XRT SDK installation path Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin The canonical installation path for the XRT SDK on Windows. ```text C:\Xilinx\XRT ``` -------------------------------- ### Verify installation Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Check that the air-opt tool is accessible. ```bash air-opt --help ``` -------------------------------- ### Install Windows development tools via winget Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Use these commands in a terminal to install the required software components for the MLIR-AIR development environment. ```batch REM Choose one: the full IDE or the matching Build Tools package winget install -e --id Microsoft.VisualStudio.Community REM winget install -e --id Microsoft.VisualStudio.BuildTools REM The package id carries the minor version; match the Python note above winget install -e --id Python.Python.3.13 winget install -e --id Git.Git REM Only needed to run the example test suites (section 6.5) winget install -e --id ezwinports.make ``` -------------------------------- ### Install MLIR-AIR Wheels via PowerShell Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Use this command to create a virtual environment and install the necessary MLIR-AIR and AIE packages. ```powershell python -m venv airenv .\airenv\Scripts\Activate.ps1 python -m pip install --upgrade pip pip install "mlir_air[aie]" ` -f https://github.com/Xilinx/mlir-air/releases/expanded_assets/latest-air-wheels ` -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-4 ` -f https://github.com/Xilinx/llvm-aie/releases/expanded_assets/nightly ``` -------------------------------- ### Build and install MLIR-AIR Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Commands to execute the build process using Ninja. ```batch cd C:\dev\mlir-air\build ninja install ``` -------------------------------- ### Set up runtime environment Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin A batch script to configure the environment variables for the MLIR-AIR installation. ```batch @echo off call "C:\dev\mlir-aie\iron_env.cmd" || exit /b 1 set "MLIR_AIR_INSTALL_DIR=C:\dev\mlir-air\install" set "PATH=%MLIR_AIR_INSTALL_DIR%\bin;%PATH%" set "PYTHONPATH=%MLIR_AIR_INSTALL_DIR%\python;%PYTHONPATH%" ``` -------------------------------- ### Verify Tool Installation Source: https://xilinx.github.io/mlir-air/dev/buildingGPU Check if required tools are available in the system path. ```bash which air-opt mlir-opt ``` -------------------------------- ### Run Element-wise Addition Example Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Executes the element-wise addition workflow using the Python builder and XRT dispatch. ```bash call air_env.cmd cd programming_examples\eltwise_add_with_l2 mkdir build_peano cd build_peano python ..\eltwise_add.py --output-format xclbin ``` -------------------------------- ### Cross-rank DMA Memcpy Example Source: https://xilinx.github.io/mlir-air/dev/AIRComputeModel Example of reading data from a remote rank's symmetric buffer into local memory. ```MLIR // Read 1024 floats from rank 0's symmetric buffer into local L1. air.dma_memcpy_nd (%local[][][], %sym[][][]) {src_rank = 0 : i64} : (memref<1024xf32, 2>, memref<1024xf32, 0>) ``` -------------------------------- ### Override MemRef Memory Space Examples Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Examples demonstrating how to override memory spaces for specific AIR hierarchy levels. ```MLIR // Override herd allocs to L1 (memory_space 2) %herd = transform.structured.match ops{["air.herd"]} in %arg1 : (!transform.any_op) -> !transform.any_op transform.air.override_memref_memory_space %herd {memory_space = 2} : (!transform.any_op) -> !transform.any_op // Override func-level allocs to L2 (memory_space 1), excluding herds %func = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op transform.air.override_memref_memory_space %func {memory_space = 1} : (!transform.any_op) -> !transform.any_op ``` -------------------------------- ### Full Compile and Run Workflow Source: https://xilinx.github.io/mlir-air/dev/buildingGPU A complete sequence for compiling and executing the matrix multiplication example in one workflow. ```bash # Setup environment source utils/env_setup_gpu.sh install # Compile aircc --target gpu --gpu-arch gfx942 \ -o /tmp/output.mlir \ test/gpu/4k_4k_mul/air_sync.mlir # Run mlir-runner --entry-point-result=void \ --shared-libs=$LLVM_INSTALL_DIR/lib/libmlir_rocm_runtime.so \ --shared-libs=$MLIR_AIR_INSTALL_DIR/lib/libairgpu.so \ /tmp/output.mlir ``` -------------------------------- ### Install MLIR-AIR with AIE backend Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Installs the MLIR-AIR package with the AIE extra, pulling necessary dependencies from specified release assets. ```batch pip install "mlir_air[aie]" ^ -f https://github.com/Xilinx/mlir-air/releases/expanded_assets/latest-air-wheels ^ -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-4 ^ -f https://github.com/Xilinx/llvm-aie/releases/expanded_assets/nightly ``` -------------------------------- ### Examples for transform.air.remove_uninitialized_copy Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Demonstrates the removal of memref.copy and linalg.copy operations when the source is uninitialized. ```MLIR // memref.copy case %alloc = memref.alloc() : memref<2x16x8xi32, 1> %subview = memref.subview %alloc[0, 0, 0] [1, 16, 8] [1, 1, 1] : ... %target = memref.alloc() : memref<1x16x8xi32, 2> memref.copy %subview, %target // <- This copy will be erased // linalg.copy case %alloc2 = memref.alloc() : memref<16x8xi32, 1> %target2 = memref.alloc() : memref<16x8xi32, 2> linalg.copy ins(%alloc2 : memref<16x8xi32, 1>) outs(%target2 : memref<16x8xi32, 2>) // <- This copy will be erased ``` -------------------------------- ### Execute air-place-herds Source: https://xilinx.github.io/mlir-air/dev/AIRTransformPasses Example command for placing herds onto a segment with specified grid dimensions and anchor points. ```text -air-place-herds"num-rows=8 num-cols=10 row-anchor=0 col-anchor=0" ``` -------------------------------- ### Configure herd size Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Runs matrix multiplication examples with different herd configurations. ```bash make run2x2 COMPILE_MODE=compile-only # 2x2 herd make run8x4 COMPILE_MODE=compile-only # 8x4 herd ``` -------------------------------- ### Clone and Setup MLIR-AIE Environment Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Initializes the MLIR-AIE repository and configures the ironenv Python environment for development. ```bash git clone --recurse-submodules https://github.com/Xilinx/mlir-aie.git C:\dev\mlir-aie cd C:\dev\mlir-aie python utils\iron_setup.py --dev call .\iron_env.cmd ``` -------------------------------- ### Linalg Elementwise Fusion Example Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Demonstrates the transformation of linalg generic operations before and after applying elementwise fusion. ```mlir // Before fusion: %0 = linalg.generic { indexing_maps = [#map0, #map1], iterator_types = ["parallel"] } ins(%input : tensor<16xf32>) outs(%temp1 : tensor<16xf32>) { ^bb0(%arg0: f32, %arg1: f32): %1 = arith.mulf %arg0, %cst : f32 linalg.yield %1 : f32 } -> tensor<16xf32> %result = linalg.generic { indexing_maps = [#map0, #map2, #map1], iterator_types = ["parallel"] } ins(%0, %input2 : tensor<16xf32>, tensor<16xf32>) outs(%temp2 : tensor<16xf32>) { ^bb0(%arg0: f32, %arg1: f32, %arg2: f32): %2 = arith.addf %arg0, %arg1 : f32 linalg.yield %2 : f32 } -> tensor<16xf32> // After fusion: %result = linalg.generic { indexing_maps = [#map0, #map2, #map1], iterator_types = ["parallel"] } ins(%input, %input2 : tensor<16xf32>, tensor<16xf32>) outs(%temp2 : tensor<16xf32>) { ^bb0(%arg0: f32, %arg1: f32, %arg2: f32): %1 = arith.mulf %arg0, %cst : f32 %2 = arith.addf %1, %arg1 : f32 linalg.yield %2 : f32 } -> tensor<16xf32> ``` -------------------------------- ### Configure Environment Variables with air_env.ps1 Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Dot-source this script to set up the required paths and environment variables for the MLIR-AIR installation. ```powershell . .\airenv\Scripts\Activate.ps1 $SP = Join-Path $env:VIRTUAL_ENV 'Lib\site-packages' $env:MLIR_AIR_INSTALL_DIR = Join-Path $SP 'mlir_air' $env:MLIR_AIE_INSTALL_DIR = Join-Path $SP 'mlir_aie' $env:PEANO_INSTALL_DIR = Join-Path $SP 'llvm-aie' $env:XRT_ROOT = 'C:\Xilinx\XRT' $env:PATH = "$env:MLIR_AIR_INSTALL_DIR\bin;$env:MLIR_AIE_INSTALL_DIR\bin;" + "$env:XRT_ROOT;$env:XRT_ROOT\lib;C:\Windows\System32\AMD;$env:PATH" $env:PYTHONPATH = "$env:MLIR_AIR_INSTALL_DIR\python;$env:MLIR_AIE_INSTALL_DIR\python;$env:XRT_ROOT\python" ``` -------------------------------- ### Example of transform.air.fuse_multi_op_linalg Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Demonstrates the fusion of two linalg operations where the first contains element-wise operations and the second performs a reduction. ```mlir // Before fusion: %0 = linalg.generic { indexing_maps = [#map0, #map1], iterator_types = ["parallel", "parallel"] } ins(%input : tensor<16x8xf16>) outs(%temp : tensor<16x8xf32>) { ^bb0(%arg0: f16): %1 = arith.extf %arg0 : f16 to f32 %2 = arith.mulf %1, %cst : f32 linalg.yield %2 : f32 } -> tensor<16x8xf32> %result = linalg.generic { indexing_maps = [#map2, #map3], iterator_types = ["parallel", "reduction"] } ins(%0 : tensor<16x8xf32>) outs(%output : tensor<16xf32>) { ^bb0(%arg0: f32, %arg1: f32): %3 = arith.addf %arg0, %arg1 : f32 linalg.yield %3 : f32 } -> tensor<16xf32> // After fusion: %result = linalg.generic { indexing_maps = [#map4, #map3], iterator_types = ["parallel", "reduction"] } ins(%input : tensor<16x8xf16>) outs(%output : tensor<16xf32>) { ^bb0(%arg0: f16, %arg1: f32): %1 = arith.extf %arg0 : f16 to f32 %2 = arith.mulf %1, %cst : f32 %3 = arith.addf %2, %arg1 : f32 linalg.yield %3 : f32 } -> tensor<16xf32> ``` -------------------------------- ### Set up environment variables Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Configure paths for MLIR-AIR, MLIR-AIE, and Peano components, and optionally source XRT. ```bash export MLIR_AIR_INSTALL_DIR=$(python3 -m pip show mlir_air | grep ^Location: | awk '{print $2}')/mlir_air export MLIR_AIE_INSTALL_DIR=$(python3 -m pip show mlir_aie | grep ^Location: | awk '{print $2}')/mlir_aie export PEANO_INSTALL_DIR=$(python3 -m pip show llvm-aie | grep ^Location: | awk '{print $2}')/llvm-aie export PATH=$MLIR_AIR_INSTALL_DIR/bin:$MLIR_AIE_INSTALL_DIR/bin:$PATH export PYTHONPATH=$MLIR_AIR_INSTALL_DIR/python:$MLIR_AIE_INSTALL_DIR/python:$PYTHONPATH export LD_LIBRARY_PATH=$MLIR_AIR_INSTALL_DIR/lib:$MLIR_AIE_INSTALL_DIR/lib:$LD_LIBRARY_PATH # Only if you have XRT installed (replace with your actual XRT install path): source /path/to/xrt/setup.sh ``` -------------------------------- ### Manual Build MLIR-AIR for GPU Source: https://xilinx.github.io/mlir-air/dev/buildingGPU Step-by-step manual configuration and build process using CMake and Ninja. ```bash # Clone and setup git clone https://github.com/Xilinx/mlir-air.git cd mlir-air source utils/setup_python_packages.sh # Build LLVM ./utils/clone-llvm.sh ./utils/build-llvm-local.sh llvm # Configure MLIR-AIR for GPU mkdir -p build_gpu && cd build_gpu cmake .. \ -GNinja \ -DMLIR_DIR=$(pwd)/../llvm/install/lib/cmake/mlir \ -DLLVM_DIR=$(pwd)/../llvm/install/lib/cmake/llvm \ -DAIR_ENABLE_AIE=OFF \ -DAIR_ENABLE_GPU=ON \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=$(pwd)/install # Build and install ninja install ``` -------------------------------- ### Set up environment variables Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Configure environment paths after building, including optional XRT support. ```bash source utils/env_setup.sh [install_dir] $(python3 -m pip show mlir_aie | grep Location | awk '{print $2}')/mlir_aie $(python3 -m pip show llvm-aie | grep Location | awk '{print $2}')/llvm-aie my_install/mlir ``` ```bash source [xrt_dir]/setup.sh ``` -------------------------------- ### Vectorize Herd Operations Example Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Example usage of the transform.air.herd_vectorize operation with specific configuration attributes. ```mlir %herd = transform.structured.match ops{["air.herd"]} in %f : (!transform.any_op) -> !transform.any_op %vectorized = transform.air.herd_vectorize %herd { vectorize_nd_extract = false, flatten_1d_depthwise_conv = false, vectorize_padding = true } : (!transform.any_op) -> !transform.any_op ``` -------------------------------- ### Install no-RTTI variant Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Install MLIR-AIR using the no-RTTI variant for compatibility with downstream projects built without RTTI. ```bash pip install 'mlir_air[aie]' \ -f https://github.com/Xilinx/mlir-air/releases/expanded_assets/latest-air-wheels-no-rtti \ -f https://github.com/Xilinx/mlir-aie/releases/expanded_assets/latest-wheels-no-rtti-2 \ -f https://github.com/Xilinx/llvm-aie/releases/expanded_assets/nightly ``` -------------------------------- ### Manual Tiling with -air-automatic-tiling Source: https://xilinx.github.io/mlir-air/dev/AIRTransformPasses Demonstrates manual loop tiling using specified tile sizes via command line arguments. ```mlir module { func.func @task(%arg0: tensor<4096xi32>, %arg1: tensor<4096xi32>) -> tensor<4096xi32> { %0 = memref.alloc() : memref<4096xi32> %1 = "aten.type_cast"(%arg0) : (tensor<4096xi32>) -> memref<4096xi32> %2 = "aten.type_cast"(%arg1) : (tensor<4096xi32>) -> memref<4096xi32> %c0 = constant 0 : index %c4096 = constant 4096 : index %c0_0 = constant 0 : index affine.for %arg2 = 0 to 4096 { %4 = affine.load %1[%arg2] : memref<4096xi32> %5 = affine.load %2[%arg2] : memref<4096xi32> %6 = muli %4, %5 : i32 affine.store %6, %0[%arg2] : memref<4096xi32> } {affine_opt_label = "air.binary_op"} %3 = "aten.type_cast"(%0) : (memref<4096xi32>) -> tensor<4096xi32> return %3 : tensor<4096xi32> } } ``` ```mlir #map = affine_map<(d0, d1, d2, d3) -> (d0 + d1 * 64 + d2 * 128 + d3 * 256)> module { func.func @task(%arg0: tensor<4096xi32>, %arg1: tensor<4096xi32>) -> tensor<4096xi32> { %0 = memref.alloc() : memref<4096xi32> %1 = "aten.type_cast"(%arg0) : (tensor<4096xi32>) -> memref<4096xi32> %2 = "aten.type_cast"(%arg1) : (tensor<4096xi32>) -> memref<4096xi32> affine.for %arg2 = 0 to 16 { affine.for %arg3 = 0 to 2 { affine.for %arg4 = 0 to 2 { affine.for %arg5 = 0 to 64 { %4 = affine.apply #map(%arg5, %arg4, %arg3, %arg2) %5 = affine.load %1[%4] : memref<4096xi32> %6 = affine.load %2[%4] : memref<4096xi32> %7 = muli %5, %6 : i32 affine.store %7, %0[%4] : memref<4096xi32> } } } } {affine_opt_label = ""} %3 = "aten.type_cast"(%0) : (memref<4096xi32>) -> tensor<4096xi32> return %3 : tensor<4096xi32> } } ``` -------------------------------- ### Create a virtual environment Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Initialize a Python virtual environment and upgrade pip. ```bash python3 -m venv airenv source airenv/bin/activate pip install --upgrade pip ``` -------------------------------- ### Quick Build MLIR-AIR for GPU Source: https://xilinx.github.io/mlir-air/dev/buildingGPU Automated script sequence to clone, build LLVM, build MLIR-AIR, and set up the environment. ```bash # Clone the repository git clone https://github.com/Xilinx/mlir-air.git cd mlir-air # Setup Python environment source utils/setup_python_packages.sh # Build LLVM ./utils/clone-llvm.sh ./utils/build-llvm-local.sh llvm # Build MLIR-AIR for GPU (without AIE) ./utils/build-mlir-air-gpu.sh llvm # Setup environment source utils/env_setup_gpu.sh install ``` -------------------------------- ### Run the build script Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Execute the build process, optionally including XRT support for hardware execution. ```bash ./utils/build-mlir-air-using-wheels.sh [build_dir] [install_dir] ``` ```bash ./utils/build-mlir-air-using-wheels.sh --xrt-dir [build_dir] [install_dir] ``` -------------------------------- ### transform.air.get_segment_for Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Gets a handle to the parent 'air.segment' of the given operation. ```APIDOC ## transform.air.get_segment_for ### Description Produces a handle to the parent `air.segment` op for each payload IR operation associated with the operand. Fails if a segment cannot be found. ### Operands - **target** (TransformHandleTypeInterface) - Required - The input operation handle. ### Results - **parent** (TransformHandleTypeInterface) - The resulting handle to the parent air.segment. ``` -------------------------------- ### Broadcast Before Unary Usage Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Examples of applying the broadcast_before_unary transform to functions. ```MLIR %func = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op transform.air.broadcast_before_unary %func ``` ```MLIR %func = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op transform.air.broadcast_before_unary %func {op_name = "math.rsqrt"} ``` -------------------------------- ### Get Segment Operation Syntax Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Syntax definition for the transform.air.get_segment_for operation. ```mlir operation ::= `transform.air.get_segment_for` $target attr-dict `:` functional-type(operands, results) ``` -------------------------------- ### Create and activate a virtual environment Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Initializes a Python virtual environment and upgrades pip. ```batch python -m venv airenv airenv\Scripts\activate.bat python -m pip install --upgrade pip ``` -------------------------------- ### Example of transform.air.fuse_truncf_linalg Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Demonstrates folding an arith.truncf operation into a producer linalg operation. ```mlir // Before fusion: %0 = linalg.generic { ^bb0(%arg0: f32, %arg1: f32): %1 = arith.addf %arg0, %arg1 : f32 linalg.yield %1 : f32 } ins(%input1, %input2 : tensor<16xf32>, tensor<16xf32>) outs(%temp : tensor<16xf32>) %result = linalg.generic { ^bb0(%arg0: f32): %2 = arith.truncf %arg0 : f32 to f16 linalg.yield %2 : f16 } ins(%0 : tensor<16xf32>) outs(%output : tensor<16xf16>) // After fusion: %result = linalg.generic { ^bb0(%arg0: f32, %arg1: f32): %1 = arith.addf %arg0, %arg1 : f32 %2 = arith.truncf %1 : f32 to f16 linalg.yield %2 : f16 } ins(%input1, %input2 : tensor<16xf32>, tensor<16xf32>) outs(%output : tensor<16xf16>) ``` -------------------------------- ### Size-1 vector to scalar usage example Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Applying the transformation to a function operation. ```mlir %func = transform.structured.match ops{["func.func"]} in %arg0 : (!transform.any_op) -> !transform.any_op transform.air.convert_size1_vector_to_scalar %func ``` -------------------------------- ### Configure Affine Loop Optimization Options Source: https://xilinx.github.io/mlir-air/dev/AIRTransformPasses List of available command-line options for the -affine-loop-opt pass. ```text -affine-opt-tile-sizes : Affine loop tiling sizes -affine-opt-copy-depths : Affine loop data copy loop depths -affine-opt-copy-fast-space : Fast memory space to use for affine data copy -affine-opt-copy-slow-space : slow memory space to use for affine data copy -affine-opt-tile-separate : Affine loop tiling separates full and partial tiles -aaffine-opt-label : Transform loops with the given label -affine-opt-post-label : Label to apply to transformed loop nest ``` -------------------------------- ### Memref to Linalg copy transformation Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Example showing the replacement of memref.copy with linalg.copy. ```mlir memref.copy %source, %dest : memref<...> to memref<...> ``` ```mlir linalg.copy ins(%source : memref<...>) outs(%dest : memref<...>) ``` -------------------------------- ### Configure environment variables Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenWin Sets up paths and environment variables required for MLIR-AIR execution. Save this as air_env.cmd. ```batch @echo off call "%~dp0airenv\Scripts\activate.bat" || exit /b 1 set "SP=%VIRTUAL_ENV%\Lib\site-packages" set "MLIR_AIR_INSTALL_DIR=%SP%\mlir_air" set "MLIR_AIE_INSTALL_DIR=%SP%\mlir_aie" set "PEANO_INSTALL_DIR=%SP%\llvm-aie" set "XRT_ROOT=C:\Xilinx\XRT" set "PATH=%MLIR_AIR_INSTALL_DIR%\bin;%MLIR_AIE_INSTALL_DIR%\bin;%XRT_ROOT%;%XRT_ROOT%\lib;C:\Windows\System32\AMD;%PATH%" set "PYTHONPATH=%MLIR_AIR_INSTALL_DIR%\python;%MLIR_AIE_INSTALL_DIR%\python;%XRT_ROOT%\python" ``` -------------------------------- ### Perform broadcast and tree-reduction of tokens with scf.parallel Source: https://xilinx.github.io/mlir-air/dev/AIRComputeModel Demonstrates how to use init tokens for broadcast dependencies and scf.reduce for merging tokens from concurrent instances. ```mlir %t_out = scf.parallel (%i, %j) = (%lb0, %lb1) to (%ub0, %ub1) step (%s0, %s1) init (%t_in) -> !air.token { // All instances may start as soon as %t_in is signaled. %t_instance = air.channel.put async [%t_in] @ch[%i, %j] … scf.reduce(%t_instance : !air.token) { ^bb0(%a: !air.token, %b: !air.token): %t_merge = air.wait_all async [%a, %b] scf.reduce.return %t_merge : !air.token } } // %t_out is signaled only when ALL instances have completed. ``` -------------------------------- ### Configure Environment Source: https://xilinx.github.io/mlir-air/dev/buildingGPU Commands to set up the environment for MLIR-AIR development. ```bash cd mlir-air source utils/env_setup_gpu.sh install ``` ```bash export PATH=/path/to/mlir-air/install/bin:/path/to/llvm/install/bin:$PATH export PYTHONPATH=/path/to/mlir-air/python:$PYTHONPATH ``` -------------------------------- ### Size-1 vector to scalar loop example Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Transformation of loop iter_args while preserving region boundaries. ```mlir // Before: %result = scf.for %i = %c0 to %c4 step %c1 iter_args(%arg = %init) -> (vector<1xf32>) { %add = arith.addf %arg, %cst : vector<1xf32> scf.yield %add : vector<1xf32> } // After: %result = scf.for %i = %c0 to %c4 step %c1 iter_args(%arg = %init) -> (vector<1xf32>) { %0 = vector.extract %arg[0] : f32 from vector<1xf32> %1 = arith.addf %0, %cst_scalar : f32 %2 = vector.broadcast %1 : f32 to vector<1xf32> scf.yield %2 : vector<1xf32> } ``` -------------------------------- ### Convert Divf Sqrt to Rsqrt Usage Source: https://xilinx.github.io/mlir-air/dev/AIRTransformOps Example of applying the convert_divf_sqrt_to_rsqrt transform to an air.herd operation. ```MLIR %herd = transform.structured.match ops{["air.herd"]} in %arg0 : (!transform.any_op) -> !transform.any_op transform.air.convert_divf_sqrt_to_rsqrt %herd ``` -------------------------------- ### Run profiling workflow Source: https://xilinx.github.io/mlir-air/dev/buildingRyzenLin Generates xclbin and instructions for use with a custom C++ test executable. ```bash make profile ``` -------------------------------- ### Annotate Refeed Loop Structure Source: https://xilinx.github.io/mlir-air/dev/AIRTransformPasses Example of a re-feed loop structure recognized by the -air-annotate-refeed pass. ```mlir scf.for %i = %c0 to %c6 step %c1 { air.channel.put @xnorm[] (%buf[] [] []) } ``` -------------------------------- ### Example of -air-place-herds transformation Source: https://xilinx.github.io/mlir-air/dev/AIRTransformPasses This snippet demonstrates the structure of an AIR module before the herd placement pass, showing the hierarchy of launch, segment, and herd operations. ```mlir #map0 = affine_map<()[s0] -> (s0 * 64)> #map1 = affine_map<()[s0] -> (s0 * 512)> #map2 = affine_map<()[s0] -> (s0 * 32)> module attributes {torch.debug_module_name = "mmult"} { func.func @forward(%arg0: memref<24576x1024xbf16>, %arg1: memref<1024x1024xbf16>) -> memref<24576x1024xbf16> { %c16 = arith.constant 16 : index %c48 = arith.constant 48 : index %cst = arith.constant 0.000000e+00 : bf16 %0 = memref.alloc() {alignment = 128 : i64} : memref<24576x1024xbf16> linalg.fill ins(%cst : bf16) outs(%0 : memref<24576x1024xbf16>) %1 = memref.alloc() {alignment = 128 : i64} : memref<24576x1024xbf16> memref.copy %0, %1 : memref<24576x1024xbf16> to memref<24576x1024xbf16> %2 = memref.alloc() {alignment = 128 : i64} : memref<24576x1024xbf16> air.launch @launch_0 (%arg2, %arg3) in (%arg4=%c48, %arg5=%c16) args(%arg6=%arg0, %arg7=%arg1, %arg8=%1, %arg9=%2) : memref<24576x1024xbf16>, memref<1024x1024xbf16>, memref<24576x1024xbf16>, memref<24576x1024xbf16> attributes {resource_type = "vckxyz", size_x = 6 : i64, size_y = 2 : i64} { air.segment @segment_0 args(%arg10=%arg2, %arg11=%arg3, %arg12=%arg4, %arg13=%arg5, %arg14=%arg6, %arg15=%arg7, %arg16=%arg8, %arg17=%arg9) : index, index, index, index, memref<24576x1024xbf16>, memref<1024x1024xbf16>, memref<24576x1024xbf16>, memref<24576x1024xbf16> attributes {resource_type = "vckxyz", size_x = 3 : i64, size_y = 2 : i64} { %c1 = arith.constant 1 : index %c2 = arith.constant 2 : index %c0 = arith.constant 0 : index %c1024 = arith.constant 1024 : index %c64 = arith.constant 64 : index %3 = affine.apply #map0()[%arg11] %4 = affine.apply #map1()[%arg10] scf.for %arg18 = %c0 to %c1024 step %c64 { %12 = memref.alloc() : memref<64x64xbf16, 1> %13 = memref.alloc() : memref<64x64xbf16, 1> %14 = memref.alloc() : memref<64x64xbf16, 1> air.dma_memcpy_nd (%12[] [] [], %arg14[%4, %arg18] [%c64, %c64] [%c1024, %c1]) {id = 1 : i32} : (memref<64x64xbf16, 1>, memref<24576x1024xbf16>) air.dma_memcpy_nd (%13[] [] [], %arg15[%arg18, %3] [%c64, %c64] [%c1024, %c1]) {id = 2 : i32} : (memref<64x64xbf16, 1>, memref<1024x1024xbf16>) air.dma_memcpy_nd (%14[] [] [], %arg16[%4, %3] [%c64, %c64] [%c1024, %c1]) {id = 3 : i32} : (memref<64x64xbf16, 1>, memref<24576x1024xbf16>) air.herd @matmul_herd_0 tile (%arg19, %arg20) in (%arg21=%c2, %arg22=%c2) args(%arg23=%12, %arg24=%13, %arg25=%14) : memref<64x64xbf16, 1>, memref<64x64xbf16, 1>, memref<64x64xbf16, 1> { %c1_0 = arith.constant 1 : index %c0_1 = arith.constant 0 : index %c64_2 = arith.constant 64 : index %c32 = arith.constant 32 : index %15 = affine.apply #map2()[%arg19] %16 = affine.apply #map2()[%arg20] scf.for %arg26 = %c0_1 to %c64_2 step %c32 { %17 = memref.alloc() : memref<32x32xbf16, 2> %18 = memref.alloc() : memref<32x32xbf16, 2> %19 = memref.alloc() : memref<32x32xbf16, 2> air.dma_memcpy_nd (%17[] [] [], %arg23[%15, %arg26] [%c32, %c32] [%c64_2, %c1_0]) {id = 4 : i32} : (memref<32x32xbf16, 2>, memref<64x64xbf16, 1>) air.dma_memcpy_nd (%18[] [] [], %arg24[%arg26, %16] [%c32, %c32] [%c64_2, %c1_0]) {id = 5 : i32} : (memref<32x32xbf16, 2>, memref<64x64xbf16, 1>) air.dma_memcpy_nd (%19[] [] [], %arg25[%15, %16] [%c32, %c32] [%c64_2, %c1_0]) {id = 6 : i32} : (memref<32x32xbf16, 2>, memref<64x64xbf16, 1>) linalg.matmul ins(%17, %18 : memref<32x32xbf16, 2>, memref<32x32xbf16, 2>) outs(%19 : memref<32x32xbf16, 2>) air.dma_memcpy_nd (%arg25[%15, %16] [%c32, %c32] [%c64_2, %c1_0], %19[] [] []) {id = 7 : i32} : (memref<64x64xbf16, 1>, memref<32x32xbf16, 2>) memref.dealloc %17 : memref<32x32xbf16, 2> memref.dealloc %18 : memref<32x32xbf16, 2> memref.dealloc %19 : memref<32x32xbf16, 2> } air.herd_terminator } air.dma_memcpy_nd (%arg16[%4, %3] [%c64, %c64] [%c1024, %c1], %14[] [] []) {id = 8 : i32} : (memref<24576x1024xbf16>, memref<64x64xbf16, 1>) memref.dealloc %12 : memref<64x64xbf16, 1> memref.dealloc %13 : memref<64x64xbf16, 1> memref.dealloc %14 : memref<64x64xbf16, 1> } air.segment_terminator } air.launch_terminator } return %2 : memref<24576x1024xbf16> } } ``` ```mlir air.herd @matmul_herd_0 tile (%arg19, %arg20) in (%arg21=%c2, %arg22=%c2) args(%arg23=%12, %arg24=%13, %arg25=%14) : memref<64x64xbf16, 1>, memref<64x64xbf16, 1>, memref<64x64xbf16, 1> attributes {x_loc = 0 : i64, y_loc = 7: i64} { ```