ods是mlir中定义自定义operation的事实标准,需通过.td文件声明式定义;最简transposeop只需命名、输入输出及方言链接,如def transposeop : toy_op { let arguments = (ins f64tensor:$input); let results = (outs f64tensor); }。

ODS(Operation Definition Specification)不是“用法选项”,而是 MLIR 中定义自定义 Operation 的事实标准方式。直接手写 C++ 类来继承 mlir::Op 既冗余又易错,ODS 通过 .td 文件声明式地描述操作结构,由 mlir-tblgen 自动产出类型安全、接口完备的 C++ 代码。
怎么写一个最简可用的 TransposeOp?
关键不是“全字段堆砌”,而是先跑通骨架:命名、输入、输出、方言链接。其他字段(verifier、parser、printer)可后续补。
以 toy 方言为例,Ops.td 中定义:
def TransposeOp : Toy_Op {
let summary = "transpose a tensor";
let arguments = (ins F64Tensor:$input);
let results = (outs F64Tensor);
}
注意三点:
-
Toy_Op必须继承自你方言已定义的基类(如def Toy_Op : Op),否则mlir-tblgen会报Unknown class 'Toy_Op' -
F64Tensor是你在Types.td或同文件中定义的 type alias,不能直接写tensor—— ODS 不解析具体形状,只认类型名 - 没有
builders字段时,生成的 C++ 类仍带默认 builder(如build(..., Value input)),但若想支持属性(如{inplace = true}),必须显式加let arguments = (ins F64Tensor:$input, BoolAttr:$inplace);
arguments 和 results 怎么区分操作数和属性?
ODS 中所有输入统一归在 arguments,但语义靠修饰符区分:
- 操作数(operand):用
Value类型 +$命名,如F64Tensor:$lhs→ 生成getLhs()和getLhsOperand() - 属性(attribute):用
Attr类型 +$命名,如BoolAttr:$inplace→ 生成getInplace(),且该值在 IR 文本中出现在{...}内 - 混合写法:
let arguments = (ins F64Tensor:$input, StrAttr:$layout, I32Attr:$offset);→ 对应 MLIR 文本:"toy.transpose"(%t) {layout = "nhwc", offset = 42} : ...
漏写 Attr 后缀(比如写成 Str:$layout)会导致 mlir-tblgen 报 Unknown type 'Str'。
为什么 verifier 编译失败或不生效?
verifier 字段生成的是 verify() 成员函数,但它**不自动调用** —— 必须确保你的 Dialect 的 initialize() 方法里注册了该 Operation,并且该 Operation 继承链中启用了验证 trait(如 HasCustomVerify)。
- 常见错误:只写
let verifier = [{ return ::verify(*this); }];,但没在 C++ 端实现::verify函数,或忘了在OpBase.td中引入HasCustomVerifytrait - 正确做法(在
.td中):let traits = ["HasCustomVerify"];,并在对应Dialect.cpp实现LogicalResult verify(TransposeOp op) { ... } - 调试技巧:在 verifier 函数里加
llvm::errs() ,然后用 <code>mlir-opt --verify-diagnostics触发验证,看是否打印
生成的 C++ 代码在哪调用?怎么接入构建系统?
mlir-tblgen 输出两个文件:Ops.h.inc(声明)和 Ops.cpp.inc(实现),它们**不能直接编译**,必须被你的 Dialect.h 和 Dialect.cpp 包含:
-
Dialect.h中:#include "Dialect/Ops.h.inc" -
Dialect.cpp中:#include "Dialect/Ops.cpp.inc" - CMakeLists.txt 中需添加
add_mlir_dialect_library并指定tblgen_files(如Ops.td),否则mlir-tblgen不会触发
最容易忽略的一点:生成的 Ops.h.inc 依赖 mlir/IR/OpDefinition.h 和你方言的头文件(如 ToyDialect.h),顺序错或缺失会导致编译器报 use of undeclared identifier 'mlir::Op'。











