Skip to content

feat: 统一 PTODSL scalar、builtin vector 与 SIMT 接口语义 - #1189

Open
mouliangyu wants to merge 6 commits into
hw-native-sys:mainfrom
mouliangyu:codex/unify-pto-scalar-surface
Open

feat: 统一 PTODSL scalar、builtin vector 与 SIMT 接口语义#1189
mouliangyu wants to merge 6 commits into
hw-native-sys:mainfrom
mouliangyu:codex/unify-pto-scalar-surface

Conversation

@mouliangyu

@mouliangyu mouliangyu commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1175

Relates to mouliangyu#583

Summary

统一 PTODSL 中普通 scalar、builtin vector 和 SIMT scalar 的作者接口,并为普通 scalar/builtin-vector value 建立统一的 PTO generic IR 表达。

本 PR 让 DSL 使用统一的 pto.* 接口,由 frontend 根据 authored type 和执行上下文选择对应的 PTO IR;普通 PTO IR 使用 signless integer carrier,需要 signedness、rounding、saturation、overflow 或 fast-math 的语义通过 operation attribute 表达。

Scope

本 PR 包含:

  • 新增 PTO generic scalar/builtin-vector operations 和 semantic attributes;
  • 统一普通算术、比较、移位、除法、余数、min/max、select、bitcast 和 conversion 的 IR 表达;
  • 统一 PTODSL scalar 与 same-shape builtin-vector 的作者接口;
  • pto.cast 按源类型和目标类型分发为 extitrunciftofftoiitof
  • 统一 pointer conversion 为 pto.castptr
  • 统一普通 typed memory access 为 pto.load / pto.store
  • 新增 pto-lower-generic-ops,将普通 generic PTO operation lower 到 arithmath 或 LLVM;
  • 适配 EmitC、VPTO LLVM emitter、pointer normalization、sync analysis 和 memory analysis;
  • 迁移仓库内旧 scalar memory operation 的使用;
  • 更新相关 IR、DSL、ISA 和用户文档。

Interface Changes

PTODSL

普通 scalar 和 same-shape builtin vector 使用统一作者接口,例如:

result = lhs + rhs
result = pto.div(lhs, rhs)
result = pto.cmp(lhs, rhs, "lt")
result = pto.cast(value, pto.f16, rounding="toward_zero")
result = pto.load(ptr, offset)
pto.store(ptr, offset, value)

DSL 根据 authored type 和执行上下文选择具体 PTO IR operation。普通 scalar/builtin-vector 操作不会自动推断为 SIMT operation。

PTO IR

普通 integer operation 使用 signless i* 类型。需要 signedness 的 operation 通过 attribute 表达,浮点和整数 operation 通过 operation name 区分,例如:

%a = pto.addi %lhs, %rhs : i32
%b = pto.addf %lhs, %rhs : f32
%c = pto.cmpi ult %lhs, %rhs unsigned : i32
%d = pto.ftoi %value unsigned : f32 -> i32
%e = pto.ftof %value round(z) : f32 -> f16

exti/trunci/ftof/ftoi/itof 是 PTO IR 的分类表达;PTODSL 作者层统一使用 pto.cast

Lowering

pto-lower-generic-ops 在共享 frontend 阶段处理普通 generic PTO operation;TileLib 或 SoftLib 展开后再次处理新生成的 generic operation。target-specialized、packed ABI、SIMT collective、atomic 和同步 operation 不由该 pass 转换。

Compatibility And Migration

  • 普通 typed memory access 从 pto.load_scalar / pto.store_scalar 迁移到 pto.load / pto.store
  • pointer conversion 从旧的 integer/pointer conversion 表达迁移到 pto.castptr
  • pto.fmin / pto.fmax 迁移到对应的 pto.min / pto.maxpto.minimum / pto.maximum
  • pto.convert 不再作为独立的 PTODSL 作者接口;
  • 旧的 scalar.* 作者模块不再作为公开入口;
  • 手写普通 PTO IR 使用 signless integer type,并为 signedness-sensitive operation 显式写 signedness attribute。

Non-goals

  • persistent fragment 和 pto.alloc_buffer 的迁移;
  • CTRL[48] 的自动设置、恢复和跨指令优化;
  • target-specialized SIMT operation 到 generic arithmetic operation 的统一;
  • pointer provenance 或其它更广泛的 pointer model 重构。

本 PR 只保留 conversion 所需的 saturation/rounding 字段和现有语义,不负责新增通用 CTRL 状态管理。

Validation

已完成:

  • native PTOAS、Python frontend 和相关 Python source 构建;
  • generic operation verifier、invalid IR 和 scalar mapping lit 测试;
  • scalar conversion、signedness、rounding、saturation 和 vector 相关测试;
  • EmitC、VPTO lowering、TileLib/SoftLib 展开相关测试;
  • SIMT float conversion CA model 端到端测试,覆盖 rounding、F2I saturation 和 F2F narrowing saturation;
  • 仓库 sample 中旧 load_scalar/store_scalar 使用迁移验证;
  • changed-code compliance checker;
  • git diff --check
  • PR CI:build、lit、VPTO simulation 和 wheel build。

@mouliangyu mouliangyu changed the title feat: 统一 PTODSL 标量接口到 pto.* feat: 统一 PTODSL 标量接口与 PTO dialect Aug 7, 2026
@mouliangyu mouliangyu changed the title feat: 统一 PTODSL 标量接口与 PTO dialect feat: 统一 PTODSL 标量接口与 PTO frontend dialect Aug 9, 2026
@mouliangyu mouliangyu changed the title feat: 统一 PTODSL 标量接口与 PTO frontend dialect feat: 统一 PTODSL 标量与 builtin vector 接口到 PTO dialect Aug 9, 2026
@mouliangyu mouliangyu changed the title feat: 统一 PTODSL 标量与 builtin vector 接口到 PTO dialect feat: 统一 PTODSL scalar 与 builtin vector 的 PTO 接口和语义 Aug 10, 2026
@mouliangyu mouliangyu changed the title feat: 统一 PTODSL scalar 与 builtin vector 的 PTO 接口和语义 feat: 统一 PTODSL scalar、builtin vector 与 SIMT 接口语义 Aug 11, 2026
@mouliangyu
mouliangyu marked this pull request as ready for review August 13, 2026 00:26
@mouliangyu
mouliangyu force-pushed the codex/unify-pto-scalar-surface branch 8 times, most recently from 848dda5 to e194ab0 Compare August 14, 2026 09:10
@mouliangyu
mouliangyu force-pushed the codex/unify-pto-scalar-surface branch 6 times, most recently from c481d8b to abf08ee Compare August 21, 2026 03:05
@@ -1,99 +1,348 @@
# 14. Arith (Shared MLIR Dialect)
# 14. Scalar and Builtin Vector Value Operations

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个md文档的名字是否需要修改

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢建议。这个章节内容已经不再是 MLIR arith dialect 的镜像,当前标题是 Scalar and Builtin Vector Value Operations,因此 14-shared-arith.md 确实有些过时。我们倾向将文件重命名为 14-generic-scalar-ops.md,标题同步为 Generic Scalar and Builtin Vector Operations。这里的 generic 表示这些 IR operation 与执行域无关,可统一适用于 scalar/builtin-vector,并在后续按语义 lower;它与 SIMT 专用 operation 相区别。这个命名是否更合适?确认后我们再同步当前文档引用。

Comment thread include/PTO/IR/VPTOOps.td
class PTO_BinaryF16F32ScalarOp<string mnemonic>
: PTO_SimtOp<mnemonic, [Pure, AllTypesMatch<["lhs", "rhs", "result"]>]> {
: PTO_ScalarOp<mnemonic, [Pure, AllTypesMatch<["lhs", "rhs", "result"]>]> {
let arguments = (ins

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] PTO_BinaryF16F32ScalarOp/PTO_FmaOp 的操作数从 PTO_SimtBinaryF16F32ValueType(f16/f32/v2f16)放宽到了 PTO_GenericFloatType(含 bf16/f64/fp8 及任意 rank 向量),但这两个类没有 verifier,而 emitter 仍只支持 f32/f16/v2f16(VPTOLLVMEmitter.cpp 的 pow lowering 对其它元素类型直接 return failure())。结果:pto.pow : f64vector<4xf32> 能通过 verify,直到 VPTO emission 深处才失败。建议收窄 ODS 约束或补 verifier。

Comment thread lib/PTO/IR/PTO.cpp Outdated
}

if (inputIsInteger && resultPtrType &&
cast<IntegerType>(inputType).getWidth() != 64) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] 相比被删除的 IntToPtrOp::verify,新 CastPtrOp::verify 丢了两项检查:(1) 结果指针元素类型的 isEmitCSupportedScalarType 校验——现在 i64 -> !pto.ptr<tensor<...>> 等后端不支持的元素类型也能通过 verify;(2) 这里的 isa<IntegerType> 会接受 si64/ui64,而旧 ODS 的 I64 只接受 signless。建议补齐元素类型检查,并把整数侧约束收紧为 signless。

Comment thread ptodsl/ptodsl/_scalar_adaptation.py Outdated
@@ -28,10 +191,25 @@ def classify_runtime_scalar_type(type_obj):
return "integer"
if any(cls.isinstance(type_obj) for cls in (BF16Type, F16Type, F32Type)):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] classify_runtime_scalar_type 只识别内建 BF16/F16/F32 和少数 !pto.* 浮点类型;而 pto.f8e4m3/pto.f8e5m2_types.py 解析为 MLIR 内建 Float8E4M3FNType/Float8E5M2Type,因此 pto.cast(f32_val, pto.f8e4m3)(标量或向量)会直接抛 TypeError: runtime scalar operators only support index/int/float values——hif8 反而可用。fp8 cast 目前是不通的,与本 PR 的 cast 完备性声明矛盾。

Location loc = op.getLoc();
Type type = op.getResult().getType();
if (isa<IndexType>(type)) {
rewriter.replaceOp(op, op.getValue());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] absi 作用在 index 上被直接替换为操作数本身(恒等)。但本文件前面 negi on index 已实现为 0 - x,即负 index 在该 IR 中可表示,此时恒等替换是静默错码。建议改为 index_cast -> math.absi -> index_cast,或在 AbsIOp::verify 中拒绝 index。

Value falseValue =
stripIntegerSignedness(rewriter, loc, op.getFalseValue());
Value result = rewriter.create<LLVM::SelectOp>(
loc, trueValue.getType(), op.getCondition(), trueValue, falseValue);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] broadcast 情形(标量 i1 条件 + 向量值)arith.select 本身就支持,这里却生成了 LLVM::SelectOp:前端阶段 IR 混入 LLVM dialect 后,arith 类 pass(如 VMILegalizeArithSelect)看不到它;且 EmitC 路径 PTOToEmitC 的 conversion target 未声明 LLVM dialect(未知 op 默认合法),llvm.select 会穿过 conversion 直到 C++ 发射阶段才失败。建议改用 arith.select,或在 EmitC 侧补 pattern。

LowerScalarMathPattern<pto::SqrtOp, math::SqrtOp>,
LowerBinaryScalarMathPattern<pto::PowOp, math::PowFOp>,
LowerFmaToMathPattern>(&getContext());
if (failed(applyPatternsAndFoldGreedily(getOperation(),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] greedy 跑完后没有检查残留 generic op:例如 pto.divi ... unsigned : indexnotifyMatchFailure 后悄悄留在 IR 里,后续各路径兜底不一致(EmitC 因 addIllegalDialect<pto> 干净报错;VPTO emitter 未把 pto dialect 标为 illegal,残留 op 会漏到 LLVM 翻译阶段才以笼统信息失败)。issue #1175 要求该 pass 结束后不得残留公共 scalar op——建议在 pass 末尾 walk 一次,对不在 documented keep-set(SIMT 硬件转换、packed math 等)内的残留 generic op 显式报错。

Comment thread tools/ptoas/ptoas.cpp
// SoftLib expansion can materialize frontend PTO scalar producers after the
// shared pre-backend lowering. Legalize those newly-created generic ops
// before VPTO LLVM emission and its final legality check.
kernelModulePM.addNestedPass<func::FuncOp>(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] kernelModulePM.nest<ModuleOp>() 本身会递归覆盖嵌套 module 内的 func,这里再 addNestedPass<func::FuncOp> 一次是等幂的重复 greedy;且在 pre-backend 块(3579-3583)该 pass 跑在 VPTOSplitCVModule 之前,child-module 那次 add 实际是死代码。建议删掉或注释说明意图。

UpdatePTOOpInfoWithPipeline(op, pto::PipelineType::PIPE_S,
/*skipIfNoMemInfo=*/true);
} else if (isa<pto::OpPipeInterface>(op)) {
// --- Case D: 带有 OpPipeInterface 的计算/搬运指令 ---

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] scalar load/store 原来走 skipIfNoMemInfo=true 的分支,现在统一走 UpdatePTOOpInfo(skip=false):未跟踪指针的 scalar 访问会生成空依赖的 PIPE_S 节点而不是被丢弃。虽有新增的保守 UpdateIntegerToPtrCastMemInfo 兜底,但建议补一个针对性的 sync 测试,确认这个行为变化符合预期。

Comment thread docs/isa/micro-isa/14-shared-arith.md Outdated
```mlir
%sum = pto.addi %lhs, %rhs overflow<nsw, nuw> : i32
%fast = pto.addf %flhs, %frhs fastmath<nnan,ninf> : f32
%half = pto.ftof %value toward_zero fastmath<nnan> : f32 -> f16

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] 示例里的 toward_zeroarith.truncf 的拼法;PTO 的实际 assembly 是 round(r/a/f/c/z/o/h)(见 PTO.cpp 的 rounding parser 以及全部 lit 测试中的 round(z)),照抄此示例会得到 parse error。另外下文 247-248 行的 rounding 列表漏了 to_odd/hybrid,也没写 verifier 强制的 scope 规则:非 SIMT ftof 仅在目标更窄时接受 rounding、非 SIMT ftoi/itof 完全拒绝 rounding、to_odd/hybrid 仅 SIMT。

`pto.trunci` is signedness-independent and may carry explicit overflow
promises. Equal-width carrier reinterpretation requires no numeric operation.
- **Cross-category conversion:** The required signedness clause selects signed
or unsigned integer interpretation. Floating-point to

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] “Floating-point to integer conversion does not saturate” 与另外两处文档矛盾:用户指南 ptodsl/docs/user_guide/06-scalar-and-pointer-ops.md 说 “always saturating”,mapping 设计文档说 F2I 是 “fixed saturating ISA behavior; PTO verification requires sat”。代码真相是分 scope/形式的:非 SIMT pto.ftoi 降为 arith.fptosi(不饱和);SIMT 硬件转换饱和且 verifySimtConversionControls 强制 sat;而裸的 SIMT pto.ftoi signed 会静默走不饱和的 arith 路径。建议在这里把 scope/形式规则写准确。

%f32 = arith.constant 2.000000e+00 : f32
%bad = pto.convert %f32 round(z) nosat signed : f32 -> i32
%bad = pto.ftoi %f32 signed round(z) : f32 -> i32
return

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] 这个文件原来覆盖的是 SIMT F2I 缺 saturation 的负例,现在被改造成非 SIMT rounding 负例;改造后 verifySimtConversionControls 的失败路径(SIMT F2I 硬件转换缺 sat、非法 rounding/type 组合、缺 signedness、int→int)在全仓零测试覆盖。建议保留本例的同时,补回一个 SIMT scope 内的转换负例。

- `pto.atomic_cas(ptr, compare, value, *, l2cache="nmfv")`

Plain scalar memory remains available through `scalar.load(...)` and
`scalar.store(...)`.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] 本文档其它部分已迁移到新接口,但这里(以及 41/96/129/158 行附近)仍以 scalar.load/scalar.store/scalar.index_cast 作为现行 API 描述;scalar.* 命名空间在本 PR 已不再是公开入口,建议同步更新,或明确标注为历史方案。

Comment thread include/PTO/IR/VPTOOps.td

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] 执行域标签不一致:load/store/sqrt/exp/log/pow/fma 已迁到 PTO_ScalarOp(“纯值语义,不影响 SIMT 合法性或 section-kind 推断”),但 ceil/floor/rint/roundPTO_UnaryFloatScalarOp,约 906 行)与 PTO_BinaryFloatScalarOp 仍是 PTO_SimtOp。同类 op 两套标签,建议统一或注明依据。

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] 第 470-476 行附近仍在介绍已删除的 API:“pto.fmin and pto.fmax accept f16, f32, bf16, vector<2xf16>...”——这两个符号在 ptodsl 中已不存在(迁移目标是 pto.min/pto.max);472 行还提到 “explicit convert modes”,convert 也不再是公开接口。另外全文缺少逐名迁移指引(scalar.load/store/cast/index_castpto.*pto.convert(...)pto.cast(..., rounding=, saturation=)fmin/fmaxmin/max),作为 breaking change 用户没有迁移表可查。

lhs = arith.IndexCastOp(IndexType.get(), _strip_integer_signedness(lhs)).result
lhs = _pto_cast(lhs, IndexType.get(), index=True)
return lhs, rhs, "index"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Major] 下面这个分支里,si32 OP ui32 时 target 取 si32target_type = lhs_type if lhs_width >= rhs_width else rhs_type),ui32 操作数经同宽 unrealized cast 按位重解释后走 signed 的 divi/remi/cmpi/shr——对大于 INT32_MAX 的无符号值结果是错的(C 的 usual arithmetic conversions 应转 unsigned)。无告警、无报错,静默错码。建议至少文档化该规则,最好对同宽混合 signedness 的 div/rem/cmp/shr 给出诊断。

@mouliangyu
mouliangyu force-pushed the codex/unify-pto-scalar-surface branch from 62d0f9a to db6206b Compare August 24, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PTODSL][SIMTVF] 梳理并重构 Scalar 与 SIMT Ops,统一公共语义并明确专用边界

3 participants