IRON: a close-to-metal Python API for AMD Ryzen AI NPUs
A close-to-metal Python API for programming AMD Ryzen™ AI NPUs (AI Engines), built on an open-source MLIR-based compiler toolchain.
At a glance
- What is it?
- The mlir-aie repository gives you a Python API that compiles down to the AI Engine array inside AMD Ryzen AI processors, with explicit control over tile placement, data movement and vectorized compute. It is aimed at researchers and performance engineers with NPU hardware in front of them.
- Who is it for?
- IRON is the right tool for someone with an AMD Ryzen AI NPU who wants to control tile placement, data movement and compute explicitly instead of hiding them behind an inference framework. It is the wrong choice if you want to run a pretrained model, if you have no NPU hardware, or if your organisation needs a supported production stack rather than an alpha-tagged compiler project.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Python in, AI Engine array out
IRON is a close-to-metal Python API for programming the AI Engines in AMD Ryzen AI processors, and the slogan the README uses for it is short enough to be the whole design brief: write Python, run it on the NPU. The `@iron.jit` decorator compiles a Python design straight to the AI Engine array, and the README states that you control tile placement, data movement and vectorized compute with nothing hidden behind a framework. The audience is explicit as well, researchers and performance engineers pushing the NPU on everything from machine learning to digital signal processing. The positioning is also careful. IRON complements mainstream inference tooling like the AMD Ryzen AI Software Platform rather than replacing it, which is the honest way to describe a tool that expects you to think about the dataflow yourself. The documentation lives at xilinx.github.io/mlir-aie, with a programming guide, a Python API reference and a directory of programming examples.
What the toolchain underneath actually compiles to
The repository is more than the Python layer. The README describes it as an MLIR-based toolchain for AI Engine-enabled devices such as AMD Ryzen AI and Versal, and it generates low-level configurations for the AI Engine portion of these devices. The hardware model it targets is specific. AI Engines are organized as a spatial array of tiles, where each tile contains AI Engine cores and or memories, and the spatial array is connected by stream switches that route data between tiles, scheduled by programmable Data Movement Accelerators. The repository provides MLIR representations at multiple levels of abstraction so that compilers and developers can program cores and describe data movement and array connectivity. Underneath sits Peano, a component that extends LLVM with the AI Engine processor as a target architecture, which is what makes integration with compiler frontends such as `clang` possible. The AIE API header library is the other half of that story, letting you write vectorized AIE core code in C++ that Peano compiles.
The vector add example, line by line
The README leads with a complete example, and it is worth reading as a tour of the API rather than as something to paste. The imports pull in `aie.iron`, the `ObjectFifo`, `Program`, `Runtime` and `Worker` types, and the `range_` control flow helper. A type alias fixes the shape of the data, `np.ndarray[(1024,), np.dtype[np.int32]]`, which is then used to declare the two buffers. The function body creates an input and an output `ObjectFifo`, defines a `core_fn` that runs on one AIE core, and builds a `Worker` from it with the consumer and producer ends of the two fifos. A separate `sequence` function handles the host side, filling the input and draining the output with `wait=True`, and a `Runtime` ties the sequence to the buffers and fifo ends. The `Program` is then constructed with the current device and resolved. The host side allocates the arrays with `iron.arange` and `iron.zeros` against the `npu` device, and the final call triggers the JIT compilation on first use, after which it is cached.
The full example as it appears in the README
Here is the example exactly as the README presents it, which is the shortest path to understanding what a design in this API looks like:
import aie.iron as iron
from aie.iron import ObjectFifo, Program, Runtime, Worker
from aie.iron.controlflow import range_
import numpy as np
data_ty = np.ndarray[(1024,), np.dtype[np.int32]]
@iron.jit
def vector_add_one(a_in, b_out):
of_in = ObjectFifo(data_ty, name="in") # host → compute tile
of_out = ObjectFifo(data_ty, name="out") # compute tile → host
def core_fn(of_in, of_out): # runs on one AIE core
a = of_in.acquire(1)
b = of_out.acquire(1)
for i in range_(1024):
b[i] = a[i] + 1
of_in.release(1); of_out.release(1)
w = Worker(core_fn, [of_in.cons(), of_out.prod()])
def sequence(a, b, in_h, out_h):
in_h.fill(a)
out_h.drain(b, wait=True)
rt = Runtime(sequence, [data_ty, data_ty, of_in.prod(), of_out.cons()])
return Program(iron.get_current_device(), rt, workers=[w]).resolve_program()
a = iron.arange(1024, dtype=np.int32, device="npu")
b = iron.zeros(1024, dtype=np.int32, device="npu")
vector_add_one(a, b) # JIT-compiles on first call, runs on the NPU, caches afterThe `@iron.jit` decorator is the pivot. The README explains that it compiles the design to an `xclbin` plus an instruction stream through the Peano compiler, and then runs it on the attached NPU. The acquire and release calls on the fifo ends, and the explicit consumer and producer wiring, are the mechanism by which you describe data movement rather than having a runtime infer it.
Host setup: BIOS, kernel 6.17 and the XDNA driver
Running anything on the NPU requires host work, and the README is specific about it. You need the latest BIOS on your laptop or mini-PC so that the NPU is enabled at all, and SecureBoot has to be turned off because unsigned drivers have to be installed, with the path given as BIOS, Security, Secure boot, Disable. The Linux kernel must be 6.17 or newer, checked with:
uname -rIf it is older, the README points at the distribution kernel update mechanism, and on Ubuntu that means installing the generic HWE kernel and rebooting:
sudo apt update
sudo apt install --install-recommends linux-generic-hwe-24.04
sudo rebootThe XDNA driver and XRT then come from the AMD PPA, with the caveat that the packaged XRT only supports Python 3.12 for `pyxrt`:
sudo add-apt-repository ppa:amd-team/xrt
sudo apt update
sudo apt install libxrt2 libxrt-npu2 libxrt-dev libxrt-utils libxrt-utils-npu amdxdna-dkms
sudo rebootYou also need to be in the `render` group to access the NPU. The documented starting point is a fresh bare-bones Ubuntu 24.04 or Ubuntu 24.10 install, and the README warns that building for other Linux distributions is experimental and support may vary, with a separate non-Ubuntu build guide for that case.
Two ways to write for the same hardware
The repository supports two distinct programming routes, and the difference matters when you decide where to spend effort. The first is IRON, where a Python design is compiled through MLIR and Peano into an `xclbin` and instruction stream, with placement and data movement expressed in Python objects. The second is the AIE API header library, where you write vectorized AIE core code in C++ and let Peano compile it, using the same compiler that now has the AI Engine as a target architecture. The choice is not stylistic. The C++ route is the lower level one and is what the AIE API is designed for, and the Python route exists so that the experimental structure of a design can be iterated on quickly and the resulting dataflow inspected. The Peano component is shared, so the two routes converge on the same compiler and the same hardware model of tiles, stream switches and DMA-scheduled data movement. The design philosophy behind the interface is described in a paper the README cites, on efficiency, expressivity and extensibility in a close-to-metal NPU programming interface.
What it costs to run and where it stops
The limits are structural rather than fixable. The first is hardware: everything here needs an AMD Ryzen AI or Versal device with the NPU enabled in BIOS, and a kernel new enough to host the driver. There is no simulator in the picture for the AI Engine part of the flow, so a design cannot be developed on a machine that lacks the part. The second is the state of the software. The newest tag is an alpha, v1.4.5-alpha.1, and the support matrix is narrow: Ubuntu 24.04 or 24.10 is the documented path, the packaged XRT supports Python 3.12 for `pyxrt`, and other distributions are explicitly experimental. The third is scope. IRON is deliberately not an inference stack. If you want to load a pretrained model and get predictions, the mainstream tooling it complements is the shorter path, and IRON is the tool for the case where that stack stops being enough. The repository layout reflects this, with `programming_guide/`, `programming_examples/`, `aie_kernels/`, `python/`, `aie_runtime_lib/`, `platforms/`, `skills/`, `utils/` and a `ROADMAP.md` at the top level.
Licensing and the shape of the repository
Project metadata lists the licence as a custom one that GitHub cannot classify, and points to the LICENSE file for the terms. The README and the source headers state the actual grant, Apache 2.0 with the LLVM exception, and the badge on the front page says the same. A `LICENSES/` directory and a `REUSE.toml` file are present, which is the REUSE convention for declaring per-file licence information, and there is a `SECURITY.md` alongside a `CONTRIBUTING.md` and a pre-commit configuration. Since this is an Apache 2.0 project, the obligations that come with it are the standard attribution and notice obligations on redistribution, and the LLVM exception exists so that code derived from LLVM can be combined with the rest of the toolchain under Apache 2.0 terms. The code itself is primarily C, with the Python layer, the MLIR passes and the runtime library all sitting in the same tree.
Editorial conclusion
IRON is the right tool for someone with an AMD Ryzen AI NPU who wants to control tile placement, data movement and compute explicitly instead of hiding them behind an inference framework. It is the wrong choice if you want to run a pretrained model, if you have no NPU hardware, or if your organisation needs a supported production stack rather than an alpha-tagged compiler project. Before you start, confirm your kernel is 6.17 or newer on Ubuntu 24.04, install the XDNA driver and XRT from the AMD PPA, and read the programming guide and mini tutorial. The last push was on 2026-10-20 with v1.4.5-alpha.1 tagged on 2026-10-15, and the project carries the Apache 2.0 licence with the LLVM exception.
Frequently asked questions
What is IRON in the mlir-aie repository?
IRON is a close-to-metal Python API for programming AMD Ryzen AI NPUs, where a Python design is compiled straight to the AI Engine array. The `@iron.jit` decorator compiles to an `xclbin` plus instruction stream through the Peano compiler and runs on the attached NPU.
What do I need on the host before running code on the NPU?
The README requires the latest BIOS with the NPU enabled, SecureBoot turned off, a Linux kernel of 6.17 or newer, and the XDNA driver and XRT installed from the AMD PPA. The packaged XRT only supports Python 3.12 for `pyxrt`, and you need to be in the `render` group to access the NPU.
Can I use mlir-aie on a distribution other than Ubuntu?
There is a non-Ubuntu build guide in the documentation, but the README states that building for distributions other than Ubuntu is experimental and that support may vary. The documented starting point is a fresh Ubuntu 24.04 or Ubuntu 24.10 install.
How is the mlir-aie project licensed?
Project metadata lists a custom licence that GitHub cannot classify and points to the LICENSE file, while the README and the source headers state Apache 2.0 with the LLVM exception. A LICENSES directory and a REUSE.toml file declare per-file licence information.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/xilinx-mlir-aie)Was this useful?