Skip to content

[Architecture] VPTO IR cache 机制应迁移到 DSL 框架侧 #210

@Zhendong404

Description

@Zhendong404

Background

当前 TileLib / TileLang 模板实例化路径中,PTOAS 在 ExpandTileOp pass 内维护了一份进程内缓存:

  • ExpandState::specCacheSpecKey 为 key 缓存已经实例化出来的 func.func
  • 命中时直接复用当前 module 中已克隆进去的实例函数
  • 未命中时,再调用 python -m tilelang_dsl.expand_helper ...,解析输出 MLIR,克隆到 module 末尾,然后写回缓存

这套机制当前能避免“同一 module 内相同 Tile op 重复实例化”,但它的职责位置更偏 PTOAS 内部实现,而不是 DSL 框架集成边界。

从架构上看,VPTO IR / TileLib 实例缓存更适合作为 DSL 框架侧能力,而不是依赖 ExpandTileOp 的进程内 DenseMap

  • 当前 cache 生命周期只在一次 pass / 一次 ptoas 进程内有效
  • cache 命中结果绑定的是 MLIR 符号克隆结果,不是一个更稳定的框架层 artifact
  • 上层框架很难复用已有实例,也无法提前控制 cache key / cache invalidation / artifact 存储

Problem

把 cache 放在 PTOAS ExpandTileOp 内部,会带来一些边界和演进问题:

  • 同一个模板实例跨 module / 跨进程 / 跨编译任务无法复用
  • 框架侧看不到也控制不了实例缓存,无法把它纳入自己的编译缓存体系
  • 当前 SpecKey、函数命名、helper 调用协议、module clone 逻辑被耦合在一起,导致 cache 语义更像 pass 内部优化,而不是稳定集成契约
  • 一旦未来希望由框架直接产出或持久化 VPTO authoring IR / 实例化结果,现在的 pass 内缓存无法自然承接
  • cache 命中与否影响 ExpandTileOp 的性能,但这一性能行为当前不能由 DSL 框架统一管理

Suggestion

建议把“实例化结果缓存”的主责迁移到 DSL / 上层框架侧,PTOAS 侧只保留最薄的一层消费逻辑。

1. 明确 cache 的归属边界

建议定义成:

  • DSL / 框架侧负责根据稳定协议计算 specialization key
  • DSL / 框架侧负责决定是否命中、如何持久化、如何失效
  • PTOAS 侧负责消费实例化结果,做 IR 接入、校验、后续 lowering

2. 将当前 pass 内 cache 语义降级为实现细节或过渡机制

ExpandTileOp 内部可以保留一个很轻量的“同进程去重”机制,但不应继续作为主要 cache 语义来源。

也就是说,理想状态应该是:

  • 主要实例缓存由框架侧管理
  • PTOAS 接收“已经选好并实例化好的 artifact”或更明确的 DSL 产物
  • pass 内缓存即使存在,也只是本地优化,而不是对外协议的一部分

3. 把 cache key 协议文档化并前移到框架侧

当前实现中已经隐含了一套 key 规则:

  • Tile: dtype + shape + valid_shape + memorySpace + config
  • View: 只按 dtype 进入 key,shape/strides/memorySpace 只参与约束检查
  • Scalar: dtype
  • 另外还有 targetopcontext_attrs

建议把这套规则整理成正式协议,并明确:

  • 哪些字段决定实例边界
  • 哪些字段只参与校验
  • key 变更时 cache invalidation 怎么做
  • DSL 版本 / 模板版本是否需要进入 key

4. 明确 PTOAS 消费的 artifact 形式

建议讨论并选定一种更稳定的框架侧产物,例如:

  • 已实例化的 authoring-form MLIR 函数
  • 可 import 的 TileLib 实例 module
  • 或者更高一层的“模板实例描述 + IR artifact”组合

核心是让 PTOAS 面向“明确产物”而不是面向“内部 helper 调用 + 进程内 cache”。

Expected outcome

  • VPTO IR / TileLib 实例缓存成为 DSL 框架能力的一部分,便于跨任务、跨模块复用
  • PTOAS 与 DSL 框架之间的边界更清晰:框架产出实例化 artifact,PTOAS 负责消费和 lowering
  • 后续如果要做编译缓存、远程缓存、增量编译、预热实例库,会更自然
  • ExpandTileOp 不再承担过多“框架缓存层”的职责

Possible acceptance criteria

  • 明确一份框架侧 specialization key 协议,并与 PTOAS 当前实现对齐或完成迁移设计
  • 设计并落地一种可由框架持久化的实例 artifact 形式
  • PTOAS 能消费该 artifact,而不是必须自己调用 helper 才能命中缓存
  • ExpandTileOp 中现有 specCache 要么退化成局部优化,要么被新的消费路径替代

Additional context

当前现状可以直接从仓内实现中看到:

  • lib/PTO/Transforms/ExpandTileOp.cppExpandState::specCache
  • buildOperandSpecsJson() / buildContextAttrsJson() 负责构造 helper 输入
  • invokeTilelangDSL() 负责 cache check -> 调 helper -> 解析 MLIR -> clone 到 module -> 回填 cache
  • docs/designs/ptoas-tileop-expand-design.md 3.2.1 / 3.2.2 已经描述了现有 SpecKey 和缓存策略

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions