AMD(Xilinx)が提供しているIRONプロジェクトの環境構築を行う。
ほとんど https://github.com/Xilinx/mlir-aie/blob/main/README.md の手順に沿って実行できるが、躓いたところを記載しておく。
環境構築
sudo apt update
sudo apt install --install-recommends linux-generic-hwe-24.04
sudo reboot
XDNAドライバのインストール
インストールスクリプトを実行するだけでは、XDNAドライバがインストールできなかった。
調べるとXRTのビルドでコケていたいのでオプションを追加して再実行することでインストールできた。
bash ./utils/build_drivers.sh
変更箇所
sudo ./build.sh -npu -opt #これだとエラーになる
sudo ./build.sh -npu -opt -disable-werror
インストールの過程が見れるようにXDNAドライバのインストールスクリプトを修正した。
Install script
#!/bin/bash
echo "Checking kernel version..."
# Check if the kernel version is at least 6.11
KERNEL_VERSION=$(uname -r | cut -d'.' -f1,2)
REQUIRED_VERSION="6.11"
if [[ "$(echo -e "$KERNEL_VERSIONn$REQUIRED_VERSION" | sort -V | head -n1)" != "$REQUIRED_VERSION" ]]; then
echo "Error: Kernel version must be at least Linux 6.11. Current version: $KERNEL_VERSION"
exit 1
fi
echo "Cloning the XDNA driver repository..."
# Clone the XDNA driver repository and initialize submodules
XDNA_SHA=deceb066418f2d53fe172a595f59413a731ccee8
git clone https://github.com/amd/xdna-driver.git
export XDNA_SRC_DIR=$(realpath xdna-driver)
cd xdna-driver
echo "Checking out commit $XDNA_SHA..."
git checkout "$XDNA_SHA"
git submodule update --init --recursive
echo "Installing XRT dependencies..."
# Install XRT dependencies
cd "$XDNA_SRC_DIR"
sudo ./tools/amdxdna_deps.sh
echo "Building XRT..."
# Build XRT
cd "$XDNA_SRC_DIR/xrt/build"
#sudo ./build.sh -npu -opt #これだとエラーになる
sudo ./build.sh -npu -opt -disable-werror
echo "Detecting Ubuntu version..."
# Detect Ubuntu version
UBUNTU_VERSION=$(lsb_release -rs)
echo "Ubuntu version detected: $UBUNTU_VERSION"
echo "Removing any existing XRT and XDNA-driver packages..."
# Find and remove any installed packages that start with "xrt"
packages=$(dpkg -l | awk '/^ii/ && $2 ~ /^xrt/ { print $2 }')
if [ -z "$packages" ]; then
echo "No packages starting with 'xrt' are installed."
else
echo "Removing the following packages:"
echo "$packages"
sudo apt-get remove -y $packages
fi
echo "Installing new XRT packages..."
# Install XRT packages based on Ubuntu version
cd "$XDNA_SRC_DIR/xrt/build/Release"
case "$UBUNTU_VERSION" in
"24.04")
sudo apt reinstall ./xrt_202510.2.19.0_24.04-amd64-base.deb
sudo apt reinstall ./xrt_202510.2.19.0_24.04-amd64-base-dev.deb
;;
"24.10")
sudo apt reinstall ./xrt_202510.2.19.0_24.10-amd64-base.deb
sudo apt reinstall ./xrt_202510.2.19.0_24.10-amd64-base-dev.deb
;;
*)
echo "Error: Unsupported Ubuntu version ($UBUNTU_VERSION). Supported versions: 24.04, 24.10"
exit 1
;;
esac
echo "Building XDNA Driver..."
# Build XDNA Driver
cd "$XDNA_SRC_DIR/build"
sudo
./build.sh -release
sudo ./build.sh -package
echo "Installing XDNA plugin..."
# Install XDNA plugin based on Ubuntu version
cd "$XDNA_SRC_DIR/build/Release"
case "$UBUNTU_VERSION" in
"24.04")
sudo apt reinstall ./xrt_plugin.2.19.0_ubuntu24.04-x86_64-amdxdna.deb
;;
"24.10")
sudo apt reinstall ./xrt_plugin.2.19.0_ubuntu24.10-x86_64-amdxdna.deb
;;
esac
echo "xdna-driver and XRT built and installed successfully."
echo "Please reboot to apply changes."
NPUを使うためのドライバの読み込み。
NPUを実行するのに毎回実行する必要があるようだ。
source utils/env_setup.sh
結果
System Configuration
OS Name : Linux
Release : 6.11.0-24-generic
Machine : x86_64
CPU Cores : 12
Memory : 60904 MB
Distribution : Ubuntu 24.10
GLIBC : 2.40
Model : B650I AORUS ULTRA
BIOS Vendor : American Megatrends International, LLC.
BIOS Version : F22b
XRT
Version : 2.19.0
Branch : HEAD
Hash : 21c69cbf48f76980b2bff7be8802414f8c1e17c8
Hash Date : 2025-04-20 23:34:16
amdxdna : 2.19.0_20250420, deceb066418f2d53fe172a595f59413a731ccee8
virtio-pci : unknown, unknown
NPU Firmware Version : 1.5.4.389
Device(s) Present
|BDF |Name |
|----------------|-------------|
|[0000:10:00.1] |NPU Phoenix |
Ryzen 5 8600Gに実装しているPhoenixのNPUが認識されていることを確認できた。
NPUの動作確認
サンプルのプロジェクトを実行する。今回はNPUでベクトル化した値に整数を加算するサンプルを実行してみる。
cd ../mlir-aie/programming_examples/basic/vector_scalar_add
python3 vector_scalar_add.py npu
Time taken: 0.00016482699993503047
module {
aie.device(npu1_1col) {
%tile_0_2 = aie.tile(0, 2)
%shim_noc_tile_0_0 = aie.tile(0, 0)
%mem_tile_0_1 = aie.tile(0, 1)
aie.objectfifo @in(%shim_noc_tile_0_0, {%mem_tile_0_1}, 2 : i32) : !aie.objectfifo<memref<64xi32>>
aie.objectfifo @in_fwd(%mem_tile_0_1, {%tile_0_2}, 2 : i32) : !aie.objectfifo<memref<32xi32>>
aie.objectfifo.link [@in] -> [@in_fwd]([] [0])
aie.objectfifo @out(%tile_0_2, {%mem_tile_0_1}, 2 : i32) : !aie.objectfifo<memref<32xi32>>
aie.objectfifo @out_fwd(%mem_tile_0_1, {%shim_noc_tile_0_0}, 2 : i32) : !aie.objectfifo<memref<64xi32>>
aie.objectfifo.link [@out] -> [@out_fwd]([] [0])
%core_0_2 = aie.core(%tile_0_2) {
%c0 = arith.constant 0 : index
%c9223372036854775807 = arith.constant 9223372036854775807 : index
%c1 = arith.constant 1 : index
scf.for %arg0 = %c0 to %c9223372036854775807 step %c1 {
%0 = aie.objectfifo.acquire @in_fwd(Consume, 1) : !aie.objectfifosubview<memref<32xi32>>
%1 = aie.objectfifo.subview.access %0[0] : !aie.objectfifosubview<memref<32xi32>> -> memref<32xi32>
%2 = aie.objectfifo.acquire @out(Produce, 1) : !aie.objectfifosubview<memref<32xi32>>
%3 = aie.objectfifo.subview.access %2[0] : !aie.objectfifosubview<memref<32xi32>> -> memref<32xi32>
%c0_0 = arith.constant 0 : index
%c32 = arith.constant 32 : index
%c1_1 = arith.constant 1 : index
scf.for %arg1 = %c0_0 to %c32 step %c1_1 {
%4 = memref.load %1[%arg1] : memref<32xi32>
%c1_i32 = arith.constant 1 : i32
%5 = arith.addi %4, %c1_i32 : i32
memref.store %5, %3[%arg1] : memref<32xi32>
}
aie.objectfifo.release @in_fwd(Consume, 1)
aie.objectfifo.release @out(Produce, 1)
}
aie.end
}
aiex.runtime_sequence @sequence(%arg0: memref<1024xi32>, %arg1: memref<1024xi32>) {
%0 = aiex.dma_configure_task_for @in {
aie.dma_bd(%arg0 : memref<1024xi32>, 0, 1024, [<size = 1, stride = 0>, <size = 1, stride = 0>, <size = 1, stride = 0>, <size = 1024, stride = 1>]) {burst_length = 0 : i32}
aie.end
}
aiex.dma_start_task(%0)
%1 = aiex.dma_configure_task_for @out_fwd {
aie.dma_bd(%arg1 : memref<1024xi32>, 0, 1024, [<size = 1, stride = 0>, <size = 1, stride = 0>, <size = 1, stride = 0>, <size = 1024, stride = 1>]) {burst_length = 0 : i32}
aie.end
} {issue_token = true}
aiex.dma_start_task(%1)
aiex.dma_await_task(%1)
aiex.dma_free_task(%0)
}
}
}
計算の様子を可視化したものが以下のようになる。
┌───────────────┐ ┌────────────────────┐
│ Host Memory │ ---> │ Shim Tile (0,0) │
└───────────────┘ └─────────┬──────────┘
│ (64xi32)
v
Mem Tile (0,1)
│ (32xi32)
v
AIE Tile (0,2)
(要素に+1演算)
│ (32xi32)
v
Mem Tile (0,1)
│ (64xi32)
v
┌───────────────┐ ┌────────────────────┐
│ Host Memory │ <--- │ Shim Tile (0,0) │
└───────────────┘ └────────────────────┘
まとめ
NPUの環境構築を行い、サンプルプログラムを実行することができた。
この記事を書いている間にV0.9からV1.0にバージョンアップしていた。
サンプルのプロジェクトやドライバのインストールに変更がありそうなので、次回はV1.0の環境構築を行ってみる。