Bufferization 后内存释放由所有权分析驱动,启用 one-shot-bufferize 和新版 buffer-deallocation 流水线,仅对 owned memref 插入 dealloc;to_buffer 生成的 memref 不归 MLIR 管理,需 host 显式释放。

Bufferization 后的内存释放由所有权分析驱动,不是手动调用 free 或 dealloc
MLIR 的 Bufferization 不生成裸指针或原始 malloc/cudaMalloc 调用,而是通过 memref 语义建模内存生命周期。释放行为完全由 pass 流水线中启用的「所有权感知(ownership-aware)」释放机制决定,而非用户插入 memref.dealloc —— 那样反而容易破坏别名关系、引发 double-free 或 use-after-free。
必须启用 buffer-deallocation 流水线,且依赖 One-Shot Bufferize 的分析结果
旧版 buffer-deallocation pass 已被弃用,它仅做简单后序扫描,无法处理跨 block 别名、DPS 操作复用、或 tensor 返回值与 outs operand 共享 buffer 的情况,极易漏掉释放或重复释放。
- 新流程要求先运行
one-shot-bufferize(带完整 AnalysisState),它会标记每个 memref 是否为「owned」、「borrowed」或「view」 - 随后必须接
buffer-deallocation(新版),该 pass 仅对ownedmemref 插入memref.dealloc,且跳过所有view和已由 runtime 管理的 buffer(如来自bufferization.to_buffer的) - 若 IR 中含函数调用边界,需额外启用
func.func的 bufferization 支持(如--bufferize-function-boundaries),否则函数参数/返回值的 ownership 无法正确传播
bufferization.to_buffer 返回的 buffer 不归 MLIR 管理,必须由外部 runtime 显式释放
当你用 bufferization.to_buffer %t 将 tensor 转为 memref,这个 memref 的 lifetime 完全脱离 MLIR 的 ownership 分析链。常见错误是期望 buffer-deallocation 自动处理它 —— 实际上它会被标记为 borrowed,pass 直接跳过。
- 典型场景:CUDA kernel 输入来自
cudaMalloc,你用bufferization.to_buffer包装后传入 linalg op;此时 MLIR 不插memref.dealloc,释放责任仍在 host 侧 - 若需 MLIR 管理,应避免
to_buffer,改用纯 tensor IR + DPS ops,让one-shot-bufferize在分析阶段将输出 alias 到输入 buffer(即 inplace) - 混合场景下,可用
memref.assume_alignment或memref.extract_aligned_pointer显式导出指针,但必须同步在 host 侧配对释放
GPU 场景下 page migration 不触发自动释放,memref.dealloc 只作用于逻辑地址空间
即使 buffer-deallocation 正确插入了 memref.dealloc,它也只通知 MLIR 运行时「该 memref 句柄作废」,不等价于调用 cudaFree。实际物理内存是否回收,取决于底层 runtime 如何映射 memref 到设备内存。
- 若 memref 来自
gpu.alloc,则memref.dealloc会被 lowering 到gpu.free - 若 memref 是 host 分配后用
bufferization.to_buffer包装的,则memref.dealloc无实际 effect,必须由 host 代码调用cudaFree或free - Unified Memory(
cudaMallocManaged)下,memref.dealloc仍只释放逻辑引用,page migration 状态由 CUDA 驱动按访问模式自动管理,与 MLIR 无关
真正容易被忽略的是:ownership 分析只在 SSA 链完整、无 external side-effect(如未建模的 runtime call)时才可靠。一旦 IR 中混入未声明 memory effect 的 external 函数,one-shot-bufferize 就可能误判 buffer 可复用,导致静默覆盖 —— 这比内存泄漏更危险。

















