保证)
MLIR的Reproducibility(可重现性)保证昨晚凌晨两点,盯着屏幕上两个本该完全相同的卷积输出,差了一个像素值。同事说“可能是浮点精度问题”,我笑了笑——如果是浮点精度,不会差得这么整齐,每个通道的最后一个元素都差1。这不是随机误差,这是确定性被破坏的典型症状。MLIR社区里有个笑话:如果你能两次运行同一个MLIR pipeline得到完全相同的输出,那你一定是在做梦。这话有点夸张,但确实戳中了痛点。今天这篇笔记,就聊聊MLIR里那些让结果“不可重现”的坑,以及官方和社区是怎么填坑的。从一次“幽灵差异”说起先还原一下当时的场景。一个简单的卷积算子,从TOSA dialect一路lower到LLVM,中间经过了若干pass。第一次跑,输出正确。第二次跑,同样的输入,同样的pipeline,结果变了。排查过程很痛苦。逐层dump中间IR,发现第一次和第二次的IR在某个pass之后出现了差异——一个循环的unroll factor从4变成了8。问题出在pass的调度顺序上,某个pass依赖了另一个pass的副作用,但MLIR的pass manager默认不保证pass的执行顺序确定性。这个案例暴露了MLIR可重现性问题的三个层次:pass调度顺序、随机数生成、以及浮点运算的关联顺序。Pass Manager的“非确定性”陷阱MLIR的PassManager默认使用一个基于拓扑排序的调度策略。听起来很科学对吧?但问题在于,当你的pipeline里有多个pass