mlir 编译器学习笔记之五 -- 开发避坑
2026/6/3 11:08:41 网站建设 项目流程

1、范围循环和索引循环的区别,

// 假设原始操作数: [A, A, A] (同一个值A被用了三次) // 范围for循环的问题: for (auto input : op.getDpsInputs()) { // 缓存了 [A, A, A] // 第一次迭代:input = A,替换为 A_conv → 操作数变为 [A_conv, A, A] // 第二次迭代:input = A(仍然是缓存的A),但实际上应该处理 A_conv // 这会导致逻辑错误! } // 索引循环的正确行为: for (size_t i = 0; i < op.getDpsInputs().size(); i++) { auto input = op.getDpsInputs()[i]; // 每次都重新获取 // 第一次迭代:input = A,替换为 A_conv → 操作数变为 [A_conv, A, A] // 第二次迭代:重新获取 op.getDpsInputs()[1] = A_conv (更新后的值) // 正确处理转换后的值! }

2、replaceAllUsesExcept处理多输入的input时需要谨慎 (output不涉及)

需要显式列出所有要排除的操作,这要求我们知道所有不应该被修改的用户

3、bufferize的实现要求操作数顺序先 所有的输入、再输出(attribute忽略)

每类方言有自己的 BufferizableOpInterfaceImpl.cpp实现bufferize,需要独立注册,其中比较关键的是maybeBuffer = getBuffer(rewriter, operand, options)获取tensor对应的memref

4、elementwise 算子的所有张量参数具有相同的轴==>reduce不符合要求,可以定义属性AllTensorParasWithSameAxesOpInterface (继承DestinationStyleOpInterface)

def AllTensorParasWithSameAxesOpInterface : OpInterface<"AllTensorParasWithSameAxesOp", [DestinationStyleOpInterface]> {

let cppNamespace = "::mlir";

let description = [{ All tensor parameters have same axes. }];

let methods = [ ];

}

5、动态shape纬度值不应该使用属性来描述,以为属性要求编译时已知,而动态shape是编译时未知的。

6、涉及op->erase();类操作可能会破坏walk迭代器,需要先收集待处理操作数,然后统一处理

7、处理函数参数时,需要先更新函数签名 (返回值处理的签名仍旧可以放到后面,因为replaceAllUses替换只能更新消费者,不能更新生产者)

bufferize时选项 -one-shot-bufferize="bufferize-function-boundaries function-boundary-type-conversion=identity-layout-map use-encoding-for-memory-space"

参数处理顺序很重要:先更新函数类型,再更新块参数类型,最后创建绑定操作

更新函数类型:func.setType(newFuncType)

更新块参数:entryBlock.getArgument(i).setType(newArgType)

8、新增的算子需要 BufferizableOpInterfaceImpl.cpp 中定义相应的bufferize方法,比如EncodingCastOp算子

struct EncodingCastOpInterface : public DstBufferizableOpInterfaceExternalModel<EncodingCastOpInterface,EncodingCastOp>

9、枚举的使用

普通 enum:enum Opcode { OP_COPY_IN},可以直接使用 OP_COPY_IN

class类enum: enum class Opcode { OP_COPY_IN},需要 Opcode::OP_COPY_IN

10、getODSOperands 是不会跳过optional参数,而getOperands是获取实际输入的参数

11、StringRef identity不拥有数据,因此原来的数据释放后,将导致值无效;需要使用std::string identity才能进行值copy; ==> StringRef 出错一般是因为传入的是局部变量

struct SymExpr final : Expr {
llvm::StringRefidentity; // 只是一个指针+长度的包装,不拥有数据
SymExpr(llvm::StringRef v, SymExprCtx *ctx)
: Expr(ExprKind::Sym, ctx), identity(v) { // 只是复制指针,不是复制数据
}
};

12、纬度值对齐

a. 动态值 IndexExpr wo = IndexExpr(output, index, &Builder);

wo.alignTo(16).getValue()
b. 静态值:outputShape = cast<RankedTensorType>(output.getType()).getShape();
llvm::SmallVector<int64_t> outputMutable(outputShape.begin(), outputShape.end());
llvm::alignTo(outputMutable[outputShape.size() - 1], 16); // 先去掉const属性

注:img2col可能需要对齐,那么需要tensor.extract_slice将对齐shape后的结果回退

13、转换生成vau_generic算子的时候需要注意操作数是否存在重叠

auto genericOp = buildVAUGeneric( rewriter, loc, srcs, scales, dsts, op.getOpLibraryCallName(), [&](OpBuilder &b, Location loc, ValueRange args) { IRMapping mapping; mapping.map(originValues, args); // 映射到新操作数的参数 auto *unitOp = b.clone(*op, mapping); // 创建一个原始操作的副本,但使用新的参数(args)替代原始操作数 b.create<bau::YieldOp>(loc, unitOp->getResults()); });

效果 bau.some_op ins(%a, %b) outs(%c)

转 bau.vau_generic ins(%a, %b, %c) { ^bb0(%arg0, %arg1, %arg2): %result = bau.some_op ins(%arg0, %arg1) outs(%arg2) yield %result}

注:上述不能处理输入、输出相同的情况,因为IRMapping是哈希表:Value -> Value

14、If some tensor.empty op in scf.for and yield it out, or some op input and output are the same iter_arg, after bufferize may create an alloc inner and yield it out 解决方法,增加memref.copy,将内部的变量复制回原来的缓冲区

15、Linalg_Op确实是为结构化运算设计的,barrier 作为控制流/同步操作不应继承它

16、mlir中结构化的 scf.if/scf.for 不会切断父 BB,分支是子区域

17、std::unordered_map<std::shared_ptr<LogicalTensor>, std::map<FractalType, std::set<Operation*>>> tensorTobeMap; 默认基于shared_ptr所管理的原始指针地址进行哈希,可能导致多次运行时存在不一致的问题。

解决方法:新增自定义的hash

18、算子插入点控制:

* setInsertionPointAfter 设置的是当前插入点,不是永久固定在某个位置。每次 create 后,插入点会自动移动到新创建的操作之后

* setInsertionPointToStart,则所有操作会连续插入在开头位置,不会自动往后排。如果插入多个算子,实际是逆序

19、MLIR中不要先删除内层操作,然后指望外层还能安全地持有它的旧指针。要么先匹配外层,要么在每次使用前重新获取内层操作的有效指针。因为MLIR 的贪婪模式重写(GreedyPatternRewriteDriver)默认采用后序遍历操作(先访问最深层的操作),且重写过程中的替换/删除操作可能使外层模式持有的指针失效

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询