关于 mlir
面向使用 MLIR 构建编译器和转换流程的开发者技能,涵盖 IR 概念、内置与自定义方言、降低流水线和 mlir-opt 命令行,也介绍 ML 编译器工作流。
主要功能
- 01MLIR 操作、区域、块和值
- 02算术、内存与控制流内置方言
- 03使用 ODS 定义自定义方言
- 04通过 ConversionPattern 编写降低流程
- 05使用 mlir-opt 处理 IR
- 06Torch-MLIR 和 IREE 工作流
适用场景
- 01设计领域专用编译器 IR
- 02将高级操作降低到 LLVM 或 GPU 方言
- 03构建渐进式降低流水线
- 04设计可复用的编译器转换原型
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill mlir安装后在 Claude Code 中输入/mlir确认已加载。
详细介绍
MLIR
用途
指导 Agent 使用 MLIR(多级 IR):操作、区域、块和值;内置方言(arith、func、memref、affine、linalg);使用 ODS 编写自定义方言;使用 ConversionPattern 编写降低 Pass;mlir-opt 命令行工具;以及 ML 编译器用例(Torch-MLIR、IREE)。
适用场景
- 构建特定领域的编译器 IR(图形、ML、硬件 DSL)
- 将高级操作降低为 LLVM 或 GPU 方言
- 编写渐进式降低流水线(linalg → 循环 → LLVM)
- 与 IREE 或 Torch-MLIR 集成,以部署 ML
- 创建可在不同方言间复用的转换 Pass
- 在合适的抽象层级上试验编译器优化
工作流
1. MLIR 结构
Module
└── func.func @main()
└── region
└── block ^bb0:
└── operations (ops) producing SSA values
关键概念:
- 操作 — 类似指令的节点(
arith.addi、memref.load) - 区域 — 块的容器(函数、控制流)
- 块 — 包含有序操作的 CFG 节点
- 值 — 操作的 SSA 结果或块参数
2. 内置方言
| 方言 | 用途 |
|---|---|
arith | 整数/浮点运算 |
func | 函数定义和调用 |
memref | 带形状/步长的缓冲区抽象 |
affine | 仿射循环嵌套、映射/集合约束 |
linalg | 结构化线性代数操作 |
scf | 结构化控制流(for、if) |
llvm | 用于最终降低的 LLVM IR 方言 |
gpu | GPU 内核启动 |
// example.mlir
func.func @add(%a: memref<4xf32>, %b: memref<4xf32>, %c: memref<4xf32>) {
%c0 = arith.constant 0 : index
%c4 = arith.constant 4 : index
scf.for %i = %c0 to %c4 step %c1 {
%av = memref.load %a[%i] : memref<4xf32>
%bv = memref.load %b[%i] : memref<4xf32>
%sum = arith.addf %av, %bv : f32
memref.store %sum, %c[%i] : memref<4xf32>
}
return
}
3. mlir-opt 命令行工具
# Parse and print
mlir-opt example.mlir
# Run canonicalization
mlir-opt example.mlir -canonicalize
# Lower affine to scf
mlir-opt affine.mlir -lower-affine
# Full pipeline toward LLVM
mlir-opt input.mlir \
--linalg-bufferize \
--convert-linalg-to-loops \
--convert-scf-to-cf \
--convert-arith-to-llvm \
--convert-memref-to-llvm \
--convert-func-to-llvm \
-o llvm.mlir
4. ODS — 操作定义规范
// MyOps.td
include "mlir/IR/OpBase.td"
def My_Dialect : Dialect {
let name = "my";
let summary = "My custom dialect";
}
class My_Op<string mnemonic, list<Trait> traits = []> :
Op<My_Dialect, mnemonic, traits>;
def AddOp : My_Op<"add", [Pure]> {
let summary = "Add two values";
let arguments = (ins AnyType:$lhs, AnyType:$rhs);
let results = (outs AnyType:$result);
let assemblyFormat = "$lhs `,` $rhs attr-dict `:` type($result)";
}
# Generate C++ from TableGen
mlir-tblgen -gen-op-defs MyOps.td -I include/ -o MyOps.cpp.inc
5. 自定义方言 C++ 实现
#include "mlir/IR/DialectImplementation.h"
#include "MyDialect.h"
#include "MyOps.cpp.inc"
void MyDialect::initialize() {
addOperations<
#define GET_OP_LIST
#include "MyOps.cpp.inc"
>();
}
#define GET_OP_CLASSES
#include "MyOps.cpp.inc"
6. 降低 Pass
#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
#include "mlir/Transforms/DialectConversion.h"
struct AddOpLowering : OpConversionPattern<my::AddOp> {
using OpConversionPattern::OpConversionPattern;
LogicalResult matchAndRewrite(my::AddOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
rewriter.replaceOpWithNewOp<arith::AddIOp>(op, adaptor.getLhs(), adaptor.getRhs());
return success();
}
};
void populateLoweringPatterns(RewritePatternSet &patterns) {
patterns.add<AddOpLowering>(patterns.getContext());
}
// In pass:
mlir::ConversionTarget target(*context);
target.addIllegalDialect<my::MyDialect>();
target.addLegalDialect<arith::ArithDialect>();
if (failed(applyPartialConversion(module, target, std::move(patterns))))
signalPassFailure();
7. 面向 ML 编译器的 linalg
%0 = linalg.matmul ins(%A, %B : tensor<128x256xf32>, tensor<256x64xf32>)
outs(%C : tensor<128x64xf32>) -> tensor<128x64xf32>
降低路径:linalg → scf 循环 → affine → llvm
8. Torch-MLIR 和 IREE
# Torch-MLIR: PyTorch → MLIR
python -m torch_mlir.tools.import-onnx --onnx-model model.onnx -o model.mlir
# IREE: MLIR → GPU/CPU executable
iree-compile --iree-hal-target-backends=llvm-cpu model.mlir -o model.vmfb
iree-run-module --module=model.vmfb --function=main
常见问题
| 症状 | 原因 | 解决方法 |
|---|---|---|
| 方言未注册 | 缺少 registerDialect | 在工具/Pass 初始化时注册 |
| ODS 构建失败 | TableGen 包含路径问题 | 检查 mlir/IR/OpBase.td 的 -I 参数 |
| 降低不完整 | 仍有非法操作 | 使用 --mlir-print-ir-after-failure 调试 |
| 模式中的类型不匹配 | Adaptor 类型错误 | 使用 OpAdaptor 类型化访问器 |
| mlir-opt 崩溃 | IR 无效 | 运行 -verify-each |
| 降低后函数为空 | 所有操作均非法,没有操作被转换 | 添加缺失的模式 |
相关技能
skills/compiler-internals/llvm-passes— LLVM Pass 对应项skills/compiler-internals/compiler-frontend— 从 AST 导入到 MLIRskills/compiler-internals/jit-compilation— JIT 编译 MLIR→LLVMskills/compilers/llvm— LLVM IR 输出目标skills/gpu/cuda— GPU 方言降低目标skills/gpu/triton-lang— 可替代的 GPU 内核 IR
评论
支持 Markdown