From beace5b25da15e128f7a8cb9159c716be5a89c9d Mon Sep 17 00:00:00 2001 From: Yetianqi <465710622@qq.com> Date: Sun, 14 Jun 2026 15:40:09 +0800 Subject: [PATCH] @ docs(hivm): bound-guided HIVM rewrite design doc set Gather the three HIVM bound/optimization docs into docs/hivm_bound_rewrite/ with a README index: - hivm_optimization_playbook.md: 5 problem classes / 21 techniques mapped to HIVM rewrites (signal -> transform -> before/after IR -> model impact), with technique <-> 5-axis gap <-> HivmOpsEditor primitive mapping. - hivm_bound_vs_diagnosis_status.md: status of analytical T_bound (Python perfbound) vs bottleneck diagnosis (C++ HIVMBottleneckDiagnoser), with file:line evidence of overlap and disconnect. - feature_bound_guided_hivm_rewriter.md: feature design / dev plan framing the optimization loop as gradient descent (loss=T_sched, floor=T_bound, gradient=gap attribution, update=HivmOpsEditor rewrite), end-to-end verification loop, module interfaces, M0-M5 milestones. Docs-only change. Cross-references updated to same-folder relative paths. Co-Authored-By: Claude Opus 4.8 @ --- docs/hivm_bound_rewrite/README.md | 28 + .../feature_bound_guided_hivm_rewriter.md | 318 ++++++++++ .../hivm_bound_vs_diagnosis_status.md | 169 ++++++ .../hivm_optimization_playbook.md | 558 ++++++++++++++++++ 4 files changed, 1073 insertions(+) create mode 100644 docs/hivm_bound_rewrite/README.md create mode 100644 docs/hivm_bound_rewrite/feature_bound_guided_hivm_rewriter.md create mode 100644 docs/hivm_bound_rewrite/hivm_bound_vs_diagnosis_status.md create mode 100644 docs/hivm_bound_rewrite/hivm_optimization_playbook.md diff --git a/docs/hivm_bound_rewrite/README.md b/docs/hivm_bound_rewrite/README.md new file mode 100644 index 0000000..eae10c9 --- /dev/null +++ b/docs/hivm_bound_rewrite/README.md @@ -0,0 +1,28 @@ +# Bound-Guided HIVM 改写 — 文档集 + +本目录汇总「基于 bound 分析结论,对 HIVM 进行自动改写」这一特性的全部设计文档。 +三份文档按「分析 → 现状 → 实现计划」递进,建议依此顺序阅读: + +| # | 文档 | 作用 | 读者 | +|---|------|------|------| +| 1 | [hivm_optimization_playbook.md](hivm_optimization_playbook.md) | **优化手册**:5 类性能问题、21 条手段逐条落到 HIVM 层(检测信号 → HIVM 变换 → before/after IR → 对模型量的影响 → 落地与合法性),含手段 ↔ 五轴 gap ↔ `HivmOpsEditor` 原语映射 | 想知道「每条优化怎么改 HIVM」 | +| 2 | [hivm_bound_vs_diagnosis_status.md](hivm_bound_vs_diagnosis_status.md) | **现状分析**:解析 `T_bound`(Python `perfbound`)与瓶颈诊断(C++ `HIVMBottleneckDiagnoser`)的能力边界、重复与断裂,带 file:line 证据 | 想知道「现在有什么、缺什么」 | +| 3 | [feature_bound_guided_hivm_rewriter.md](feature_bound_guided_hivm_rewriter.md) | **特性设计/开发计划**:把优化循环建模成梯度下降(loss=`T_sched`、floor=`T_bound`、梯度=gap 归因、更新=`HivmOpsEditor` 改写),含端到端验证循环、模块接口、M0–M5 里程碑与验收标准 | 下一位基于 AI agent 做实现的开发者 | + +## 一句话主线 + +``` +检测 (诊断: 主导 gap) → 改写 (HivmOpsEditor 应用对应手段) → 重评 (perfbound 重算 T_bound/T_sched) + ▲ │ + └────────────────── 迭代收敛 (贪心坐标下降 / 梯度下降类比) ◀──────────┘ +``` + +- **(A) 缩小 gap**:`T_bound` 不变,`T_sched` 向下界收敛。 +- **(B) 降低 bound**:`T_bound` 自身下移,且守住 `T_bound ≤ T_measured`。 + +## 关联代码(已在本分支 `integrate/pr20-pr17`) + +- 改写执行器:`include/AscendModel/Transforms/HivmOpsEditor.h`、`tools/hivm-crud/` +- 诊断:`lib/AscendModel/Analysis/HIVMBottleneckDiagnosis.cpp` +- 解析 bound:`perfbound/model/bounds.py`、`perfbound/combine/bound_combiner.py` +- 规格:`.omc/specs/performance_bound_model.md` diff --git a/docs/hivm_bound_rewrite/feature_bound_guided_hivm_rewriter.md b/docs/hivm_bound_rewrite/feature_bound_guided_hivm_rewriter.md new file mode 100644 index 0000000..b2b3d9c --- /dev/null +++ b/docs/hivm_bound_rewrite/feature_bound_guided_hivm_rewriter.md @@ -0,0 +1,318 @@ +# 特性设计文档:Bound-Guided HIVM 自动改写器 + +> **一句话**:把「算子性能优化」建模成一次**梯度下降**——以 HIVM IR 为可训练参数、以解析调度时间为 +> 损失、以 bound 分析的 gap 归因为梯度、以 `HivmOpsEditor` 的 IR 改写为参数更新,迭代产出**优化后的 +> `.npuir.mlir`**,并用端到端验证循环保证每步「确实更快、且不违反理论下界」。 +> +> **内容**:本文将给出方案、形式化、模块接口、里程碑与验收标准。 +> +> **上游依据**(同目录):`hivm_optimization_playbook.md`(21 条手段 → HIVM 重写规范)、 +> `hivm_bound_vs_diagnosis_status.md`(bound/诊断现状与 file:line 证据)、 +> `.omc/specs/performance_bound_model.md`(两层上界模型)。 + +--- + +# 第一部分 · 整体方案 + +## 1. 背景与目标 + +仓库已具备三块互补能力,但它们彼此独立、未闭环(详见 `hivm_bound_vs_diagnosis_status.md`): + +1. **解析 bound(Python `perfbound`)**:从 HIVM 算 `T_bound = max(T_grid, T_core+T_serial)` + 5 轴 gap 归因 + 双下界。 +2. **瓶颈诊断(C++ `HIVMBottleneckDiagnoser` / Python `profile_utilization`)**:把瓶颈分到 5 类并给优化建议。 +3. **HIR 改写执行器(C++ `HivmOpsEditor` / `hivm-crud`)**:MLIR 原生 load→改写 `hivm.*` op→export,**真正产出优化后 HIVM**。 + +**目标**:把三块串成一个**自动优化循环**——输入一份 `.npuir.mlir`,输出一份经多步改写、可编译、被模型证明 +更优的 `.npuir.mlir`,全过程无需人工逐条试错,且每步可解释(归因到具体 gap 与具体改写)。 + +**为什么是「梯度下降」**:kernel 优化天然是「评估当前状态 → 找最痛的瓶颈(方向)→ 走一步改写 → 重新评估」的 +迭代收敛过程。这与训练中「前向→反向→更新」同构。借用这套词汇能让循环、收敛、早停、约束、checkpoint +都有现成且严谨的定义,便于 AI agent 实现与调参。 + +## 2. 核心思想:优化循环 ≅ 训练循环 + +| 训练概念 | 本系统对应 | 来源 / 实现 | +|----------|-----------|------------| +| 参数 θ(weights) | HIVM IR:`.npuir.mlir` 的 op 序列与属性 | `HivmOpsEditor` 加载的 `ModuleOp` | +| 前向 forward | 调度 + 建模:`tritonsim-hivm` → `des.json` → `perfbound` | §6 forward harness | +| **损失 L(θ)** | `T_sched(θ)`:当前 IR 的**解析调度时间**(DES 关键路径,无需硬件) | `des.json` 的 `max(end_cycle)/clock_ghz` | +| 不可约下界(≈ Bayes error) | `T_bound(θ)`:该 IR 的理论可达最小时间 | `perfbound.compute_bounds/combine` | +| 梯度 ∇L(方向) | 诊断给出的「主导 gap + locus op + 推荐手段」 | `HIVMBottleneckDiagnoser` / gap 归因 | +| 候选步集 / 动作空间 | 21 条手段 → `HivmOpsEditor` 原语(playbook §9 映射) | §7.3 动作表 | +| 学习率 / step | 一次改写的粒度(一条 rewrite primitive 作用于一组 op) | actuator 单步 | +| 参数更新 θ←θ−η∇L | 用 `HivmOpsEditor` 应用所选改写,导出新 IR | `hivm-crud --apply` | +| 一个 step/epoch | 一轮 detect→select→rewrite→re-eval | §6 loop | +| mini-batch / 探索宽度 | beam 宽度 B(同时评估 top-B 候选,取最优) | 可选 | +| 收敛 | 无 gap 超阈值 ∨ L 不再下降 ∨ 无合法改写 | §7.4 | +| 早停 | 连续 k 步无改善 ∨ 触发约束回滚 | §7.4 | +| 正则 / 约束 | 合法性(RAW/WAR/buffer 容量/IR verify)+ bound 守恒 | guard,§7.5 | +| checkpoint | 每步导出的 `.npuir.mlir` + bound 快照 | history | +| 学习曲线 | `T_sched` 随 step 的下降曲线 + 各 gap 占比变化 | history 报告 | + +> **诚实标注**:参数空间是**离散**的(op 与属性),所以严格说这是**贪心坐标下降 / best-improvement +> 搜索**(可加 beam → 近似 mini-batch),不是连续 SGD。「梯度下降」是**教学映射**,用于定义损失、方向、 +> 步长、收敛与约束;实现按 §6 的离散贪心循环来写。 + +### 损失与下界的关系(关键设计) + +- **L(θ) = T_sched(θ)**:DES 调度出的关键路径时间,是**便宜、可微观归因、无需硬件**的代理目标。 + 循环全程最小化它。 +- **T_bound(θ)**:理论下界,`T_sched ≥ T_bound` 恒成立(调度跑不过下界)。两类改写区别由它刻画: + - **(A) 缩小 gap**:`T_bound` 不变,`T_sched` 向 `T_bound` 收敛(消除可避免的串行/低效)。 + - **(B) 降低 bound**:`T_bound` 自身下移(减流量/增算术强度/融合),`T_sched` 随之绝对下降。 +- **归一化损失** `L_norm = (T_sched − T_bound) / T_bound ≥ 0`:衡量「还剩多少是可优化的 gap」。 + (A) 类把 `L_norm → 0`;(B) 类把分母也压下去。报告同时给 `T_sched`(绝对)与 `L_norm`(gap 占比)。 + +## 3. 系统全景 + +```mermaid +flowchart TD + IN[".npuir.mlir θ₀"] --> FWD + subgraph LOOP["优化循环 (贪心坐标下降)"] + FWD["前向 forward
tritonsim-hivm → des.json
L=T_sched, floor=T_bound, gap 归因"] + GRAD["梯度 ∇L
诊断: 主导 gap + locus op
→ 候选改写 (按 ΔL 排序)"] + STEP["参数更新
HivmOpsEditor 应用所选改写
→ θ'"] + GUARD["约束投影 guard
IR verify + 依赖合法 + bound 守恒
L(θ') GRAD --> STEP --> GUARD + GUARD -->|"接受 θ←θ'"| FWD + end + GUARD -->|"收敛/早停"| OUT[".npuir.mlir θ*
← 输出优化后 HIVM"] + OUT --> VAL["离线验证集
bishengir 编译 + msprof 实测
核对 T_bound ≤ T_measured、预测 vs 实测改善"] +``` + +## 4. 概念与符号定义(实现需严格对齐) + +| 符号 | 含义 | 计算来源 | +|------|------|----------| +| `θ` | 当前 HIVM IR(`.npuir.mlir`) | 文件 / `ModuleOp` | +| `T_sched(θ)` | 解析调度时间(µs)= `max(op.end_cycle)/clock_ghz` | `des.json`(`emitDESGraph` 已含 `start_cycle/end_cycle/clock_ghz`) | +| `T_bound(θ)` | 两层解析下界(µs) | `perfbound.combine.bound_combiner.combine → BoundResult.t_bound_us` | +| `gap_frac[k]` | 第 k 轴 gap 占 `T_bound` 比例 | `BoundResult.attribution`(grid/gap1..4) | +| `diag(θ)` | 诊断结果:每 op/流水/全局的 `BottleneckType` + locus + 建议 | `HIVMBottleneckDiagnoser`(需补 JSON 输出) | +| `L(θ)` | 损失 = `T_sched(θ)` | 同上 | +| `floor` | `T_bound(θ)` | 同上 | +| `δ` | 接受改写的最小 loss 改善量(µs 或相对) | 配置 | +| `ε` | 收敛阈值(`L_norm` 或主导 gap_frac) | 配置 | +| `k_patience` | 早停耐心步数 | 配置 | +| `B` | beam 宽度(每步评估的候选数,默认 1=纯贪心) | 配置 | + +## 5. 现有可复用组件(不要重造) + +| 能力 | 复用对象 | 位置 | 备注 | +|------|----------|------|------| +| 前向调度 + `des.json` | `tritonsim-hivm --npuir-file --des-graph-file` | `tools/tritonsim-hivm` | `des.json` 已含 per-op `start/end_cycle`、`clock_ghz` | +| 提取 → `HIVMExtract` | `extract_from_npuir` | `perfbound/extract/hivm_runner.py:41` | 子进程封装,可直接调 | +| 算 bound + gap | `compute_bounds` / `combine` | `perfbound/model/bounds.py`、`combine/bound_combiner.py` | `BoundResult` 即 floor+gap | +| 双下界 / headroom | `compute_two_limit` | `perfbound/combine/two_limit.py` | 报告用 | +| 诊断(IR 时刻) | `HIVMBottleneckDiagnoser` | `lib/AscendModel/Analysis/HIVMBottleneckDiagnosis.cpp` | **当前仅文本输出,需补 JSON** | +| HIR 改写执行器 | `HivmOpsEditor` | `include/AscendModel/Transforms/HivmOpsEditor.h` | 已含 `insertDoubleBuffering`/`fuseConsecutiveComputeOps`/`removeRedundantLoadStorePair`/`addSetFlagWaitFlag*`/`changeShape`… | +| 改写 CLI | `hivm-crud` | `tools/hivm-crud/hivm-crud.cpp` | **仅固定 demo 模式,需扩展为通用 `--apply spec.json`** | +| JSON 投影 counterfactual | `validate/hivm_edits.py`、`counterfactual.py` | `perfbound/validate/` | 无 bishengir 时的代理路径 | + +## 6. 范围与非目标 + +**在范围内**:单 kernel、单核(busiest core)IR 的自动多步改写;(A)+(B) 两类手段;解析驱动的收敛; +离线验证集核对。 + +**非目标**(本特性不做):① 重新标定硬件常数(A.1 校准已固定);② 跨 kernel/全网搜索;③ 在循环内做真机 +编译-运行(循环保持解析,硬件只在 §10 离线验证出现);④ 修改 Triton DSL 或 grid(Tier-1 由上游 DSL extractor 提供,本循环聚焦 Tier-2 核内改写,grid 仅作为只读约束)。 + +--- + +# 第二部分 · 开发计划 + +## 7. 把循环形式化(实现前必须钉死的契约) + +### 7.1 损失评估器 `LossEvaluator` + +```python +# perfbound/optimize/loss.py +@dataclass +class Eval: + t_sched_us: float # L(θ) + t_bound_us: float # floor + l_norm: float # (t_sched - t_bound)/t_bound + gap_frac: dict[str, float] # {"grid","gap1",...,"gap4"} + binding: str # binding component/tier + schedule_truncated: bool # des.json 标志,截断则该评估不可信 + raw_des_path: Path + +def evaluate(npuir_path: Path, *, hw_config: Path | None = None, + arg_bindings: dict[str,int] | None = None) -> Eval: + """前向:跑 tritonsim-hivm 出 des.json,算 T_sched 与 T_bound/gap。 + T_sched = max(op.end_cycle for op in des.operations) / des.clock_ghz (µs) + 复用 extract_from_npuir + compute_bounds/combine。""" +``` + +> 实现注意:`T_sched` 直接从 `des.json` 读,**无需新增 C++**(字段已存在)。若 `schedule_truncated=true` +> 必须把该 step 标为无效并早停(DES 命中 maxIterations,结果不可信)。 + +### 7.2 梯度(诊断 → 候选改写)`GradientProvider` + +```python +# perfbound/optimize/gradient.py +@dataclass +class Candidate: + rewrite: str # 原语名, e.g. "barrier_to_p2p" + locus_op_ids: list[int] # 作用的 op(des.json id) + params: dict # 原语参数 + est_delta_loss_us: float # 预估 ΔL(用 gap 归因近似,越负越好) + gap_axis: str # 归属 gap,用于解释 + kind: str # "A"(缩 gap) | "B"(降 bound) + +def candidates(ev: Eval, diag: DiagReport) -> list[Candidate]: + """把诊断主导 gap + locus 映射成排序后的候选改写。 + 映射表见 §7.3;est_delta_loss 用对应 gap 的绝对 µs 作一阶近似。""" +``` + +诊断来源二选一(建议先用 C++,实测口径作交叉校验): +- C++ `HIVMBottleneckDiagnoser`:**需补 `emitDiagnosisJSON()`**(当前只 `print` 文本)。 +- Python `analyze_operator_bottleneck`(`profile_utilization.py:235`):现成,但口径是实测式,循环内用调度量替代实测量即可。 + +### 7.3 动作空间(手段 → `HivmOpsEditor` 原语,摘自 playbook §9) + +| gap 轴 | 手段 | rewrite 名 | `HivmOpsEditor` 原语 | kind | +|--------|------|-----------|---------------------|------| +| Gap3 | 双缓冲重叠 | `double_buffer` | `insertDoubleBuffering` | A | +| Gap3 | barrier→p2p | `barrier_to_p2p` | `addSetFlagWaitFlag*`+`deleteSyncOpsForOp` | A | +| Gap2/MTE | 减冗余搬运 | `dedup_gm_trip` | `removeRedundantLoadStorePair`/`deleteRedundantGMTrips` | A/B | +| Gap4 | 融合向量 | `fuse_vector` | `fuseConsecutiveComputeOps` | A | +| Gap3 | prefetch→L1 | `prefetch_l1` | `addND2NZ*`+`changeMemorySpace` | A | +| floor | 增大 tile/K | `enlarge_tile` | `changeShape`/`addMmadL1*` | B | +| Gap3+grid | CV split | `cube_vector_split` | `addSyncBlockSet/Wait*` | A | + +> **首批只实现 kind=A 且原语为「直接便捷方法」的三条**:`double_buffer`、`fuse_vector`、`dedup_gm_trip` +> (零新原语,最快打通端到端)。其余在后续里程碑补。 + +### 7.4 收敛与早停 + +``` +收敛(任一): L_norm ≤ ε + ∨ max gap_frac ≤ ε + ∨ 候选集为空(无合法改写) +早停(任一): 连续 k_patience 步 ΔL > −δ(无实质改善) + ∨ schedule_truncated + ∨ step ≥ max_steps +``` + +### 7.5 约束投影(guard)—— 正则项,硬约束,违反即回滚 + +每步 `θ→θ'` 后必须全部通过,否则回滚并尝试下一候选: + +1. **IR 合法**:`HivmOpsEditor` 导出的 IR 能被 `tritonsim-hivm` 重新解析(parse + verify 不报错)。 +2. **依赖合法**:不破坏 RAW/WAR(用 `read/write_buffers`+`*_versions` 校验);不超 buffer 容量 + (`enlarge_tile` 须过 `UnifiedTilingCostModel` buffer check)。 +3. **下界守恒**:(A) 类改写后 `T_bound` 不变(容差内);(B) 类改写后 `T_bound` 下降且仍 `≥` 不可违反。 +4. **单调改善**:`L(θ') ≤ L(θ) − δ`,否则拒绝(best-improvement)。 + +## 8. 端到端验证循环(伪代码:训练主循环) + +```python +# perfbound/optimize/loop.py +def optimize(npuir_path, cfg) -> OptimizeResult: + theta = checkpoint0 = npuir_path + ev = evaluate(theta) # forward + history = [Snapshot(step=0, theta=theta, ev=ev)] + no_improve = 0 + + for step in range(1, cfg.max_steps + 1): + if converged(ev, cfg) or ev.schedule_truncated: + break + diag = diagnose(theta) # C++/Python 诊断 + cands = rank(candidates(ev, diag)) # 梯度:按 est_delta_loss 排序 + applied = None + for cand in cands[:cfg.beam]: # mini-batch / line search + theta2 = actuate(theta, cand) # 参数更新 (HivmOpsEditor) + if not guard_legal(theta, theta2, cand): # 正则/约束 + continue + ev2 = evaluate(theta2) # 重新前向 + if guard_bound(ev, ev2, cand) and ev2.t_sched_us <= ev.t_sched_us - cfg.delta: + applied = (theta2, ev2, cand); break + if applied is None: + no_improve += 1 + if no_improve >= cfg.k_patience: break + continue + theta, ev, cand = applied # accept θ←θ' + no_improve = 0 + history.append(Snapshot(step, theta, ev, cand)) # checkpoint + 学习曲线 + + return OptimizeResult(best=theta, history=history, + report=render(history)) # T_sched 下降曲线 + 每步归因 +``` + +**离线验证集(§3 下半部,训练完做一次,对应「测试集评估」)**: +对 n≥3 个验证 kernel 跑 `optimize`,再用 `perfbound/validate/{counterfactual,harness}.py` + +`bishengir` 编译 + `msprof` 实测,核对两件事: +1. **守恒**:`T_bound ≤ T_measured`(理论从未高估速度); +2. **方向正确**:预测的 `T_sched` 改善与实测时间改善同号、量级相符(不要求精确,要求趋势一致)。 + +## 9. 模块分解与落点 + +``` +perfbound/optimize/ ← 新增 Python 包(编排器 = optimizer) + __init__.py + loss.py # LossEvaluator: evaluate() → Eval (§7.1) + gradient.py # GradientProvider: candidates() (§7.2/7.3) + actuator.py # 调 hivm-crud/HivmOpsEditor 应用改写 (§7.3) + guard.py # 合法性 + 下界守恒 + 单调改善 (§7.5) + loop.py # optimize(): 主循环 + history (§8) + report.py # 学习曲线/归因报告 (md + 可选 json) + cli.py # python -m perfbound.optimize --kernel ... + +C++ 侧改动(最小): + HIVMBottleneckDiagnosis.{h,cpp} ← 补 emitDiagnosisJSON()(机器可读诊断) + tools/hivm-crud/hivm-crud.cpp ← 扩展 --apply :按 spec 顺序调原语 + (可选)include/.../HivmOpsEditor.h ← 若需 reorder,新增 moveOpBefore/After +``` + +**`hivm-crud --apply spec.json` 契约**(actuator 与 CLI 的接口,先钉死): +```json +{ "rewrites": [ + {"primitive": "insertDoubleBuffering", + "target_op_id": 7, "params": {"set_pipe":"PIPE_V","wait_pipe":"PIPE_MTE2","event_id":2}} +] } +``` +CLI 加载 `.npuir.mlir.bak` → 按 `rewrites` 顺序在对应 op 上调 `HivmOpsEditor` 方法 → `exportToFile`。 + +## 10. 里程碑与验收标准 + +| 里程碑 | 内容 | 验收标准(DoD) | +|--------|------|----------------| +| **M0 契约** | 定下 `Eval`/`Candidate`/`spec.json`/诊断 JSON 四个 schema | 四个 schema 写成 `docs/` + 失败测试占位;评审通过 | +| **M1 前向** | `loss.evaluate()`:从 `des.json` 算 `T_sched` + 复用 `compute_bounds` | 对 `test/hivm_add_kernel`、`hivm_mixed_cv_kernel` 输出 `Eval`,`T_sched ≥ T_bound`、`l_norm ≥ 0`;有单测 | +| **M2 执行器** | `hivm-crud --apply spec.json` + `actuator.py`;首批 3 原语 | 对两个 fixture round-trip:应用 `double_buffer`/`fuse_vector`/`dedup_gm_trip` 后导出 IR 可被重新解析;`verify_edit_via_extract` 报告模型可见变化 | +| **M3 梯度** | `HIVMBottleneckDiagnoser::emitDiagnosisJSON` + `gradient.candidates()` | 诊断 JSON 含 per-op `BottleneckType`+locus;`candidates()` 对「故意注入 PIPE_ALL barrier」的 fixture 给出 `barrier_to_p2p`/`double_buffer` 候选并排序 | +| **M4 闭环** | `guard.py` + `loop.optimize()` + `report.py` | 对 ≥2 fixture:循环在 `max_steps` 内收敛或正确早停;`T_sched` 单调不增;产出优化后 `.npuir.mlir` + 学习曲线;每步归因可读;非法改写被回滚 | +| **M5 验证集** | 离线 `bishengir` 编译 + `msprof` 核对 | n≥3 kernel:`T_bound ≤ T_measured` 全部成立;预测改善与实测改善同号 | + +## 11. 测试策略 + +- **单元**:`loss`(`T_sched` 计算、截断处理)、`gradient`(映射表、排序)、`guard`(注入非法改写须拒绝)、 + `actuator`(spec→IR diff)。 +- **集成**:fixture 上跑完整 `optimize`,断言收敛/早停、单调性、IR 可重解析。 +- **counterfactual 一致性**:同一手段的 JSON 代理(`hivm_edits.py`)与真实 HIR 改写(`HivmOpsEditor`) + 对模型量的影响方向一致(防止两条落地实现语义漂移)。 +- **回归**:现有 `tests/perfbound/*` 全绿(不破坏 bound/extract)。 + +## 12. 风险与缓解 + +| 风险 | 影响 | 缓解 | +|------|------|------| +| `T_sched`(DES 估计)与真机偏差 | 循环朝错误方向走 | M5 验证集核对趋势;偏差大的手段先只信「方向」不信「幅度」 | +| 贪心陷局部最优 | 错过更优组合 | beam(B>1)+ 随机重启;记录被拒候选供分析 | +| `HivmOpsEditor` 需 bishengir 方言(`TRITONSIM_HAS_BISHENGIR_HIVM`) | 无方言环境跑不动改写 | 退回 `hivm_edits.py` JSON 代理路径跑循环(产物为 JSON 而非可编译 HIR),CI 双轨 | +| 合法性判定不全引入 race | 产出错误 kernel | guard 默认保守:依赖不确定一律拒绝;M5 编译实测兜底 | +| 诊断两套口径漂移(C++ vs Python) | 候选不稳定 | M3 用同一组 fixture 交叉校验,差异写回 status 文档 | +| reorder 无底层原语 | §3③ 手段缺失 | 标记为 M4 之后;先用 delete+create 间接或新增 `moveOp` | + +## 13. 给实现者的最小起步清单 + +1. 建 `perfbound/optimize/` 骨架与 `cli.py`(`python -m perfbound.optimize --kernel k.npuir.mlir`)。 +2. 实现 `loss.evaluate()`(M1)——这是最小可跑前向,先让 `T_sched/T_bound` 在两个 fixture 上出数。 +3. 扩展 `hivm-crud --apply spec.json` + `actuator.py`,接通**一条** `fuse_vector`(M2)。 +4. 用「写死单条候选」的最简 `loop`(跳过诊断)跑通 detect→rewrite→re-eval→guard 一圈,验证 `T_sched` 下降。 +5. 再补 `emitDiagnosisJSON` + `gradient`(M3),把「写死候选」换成「诊断驱动候选」。 +6. 补 `guard`/`report`/早停,做成完整循环(M4),最后接离线验证(M5)。 + +> 实现顺序的原则与训练一致:**先让 forward+loss 能算,再让 update 能走一步,再让 gradient 指方向, +> 最后加约束与早停**。每步都能在 `test/*.npuir.mlir` 上独立验收,避免一次性大改。 diff --git a/docs/hivm_bound_rewrite/hivm_bound_vs_diagnosis_status.md b/docs/hivm_bound_rewrite/hivm_bound_vs_diagnosis_status.md new file mode 100644 index 0000000..4e8d81e --- /dev/null +++ b/docs/hivm_bound_rewrite/hivm_bound_vs_diagnosis_status.md @@ -0,0 +1,169 @@ +# 现状分析:基于 HIVM 的「bound」与「诊断」是否已具备 + +> 分支:`integrate/pr20-pr17`(已 cherry-pick PR#20 `HivmOpsEditor` + PR#17 `HIVMBottleneckDiagnosis`)。 +> 问题:**目前基于 HIVM 分析出 bound 的逻辑是否已经有了?** +> 一句话结论:**「基于 HIVM 算解析 T_bound」的逻辑早就有了——在 Python `perfbound` 侧; +> 刚合入的 PR#17 加的是「瓶颈诊断 + 优化建议」,不是 bound。两者目前彼此独立、未打通。** + +把三件事分清,因为它们在仓库里是**三套独立**的东西: + +| 层 | 是什么 | 在哪 | 产出 | 状态 | +|----|--------|------|------|------| +| **A. 解析 T_bound** | 两层上界模型(spec) | Python `perfbound/` | `BoundResult.t_bound_us` + 5 轴归因 + 双下界 | ✅ 已有,端到端接通,有测试 | +| **B. 瓶颈诊断** | 从 HIVM 调度结果做根因分类 + 建议 | C++(PR#17) | `HIVMBottleneckReport`(6 类 + suggestions) | ✅ 新合入,已接 CLI;**非 bound** | +| **B′. 瓶颈诊断(实测口径)** | 同一套 5 类分类,从 realized A/I/U/R/E | Python `profile_utilization` | `OperatorBottleneckReport` | ✅ 已有(与 B 重复) | + +--- + +## A. 真正的解析 T_bound —— ✅ 已存在(Python `perfbound`),已接通且有测试 + +消费的是 C++ 导出的 **HIVM DES-graph JSON**(schema `a3_hivm_des_v1`),不是裸 IR。 + +### 端到端链路(含 file:line 证据) + +``` +.npuir.mlir + └─ extract_from_npuir() perfbound/extract/hivm_runner.py:41 + └─ subprocess: tritonsim-hivm --npuir-file … --des-graph-file des.json + └─ extract_hivm(des.json) → HIVMExtract perfbound/extract/hivm_extractor.py + └─ compute_bounds(grid_info, extract, calib_db) perfbound/model/bounds.py:44 + ├─ compute_component_floor → ComponentBound (Tier2:调和均值 I_c、t_core_floor) + │ perfbound/model/component_model.py:164 + ├─ compute_grid_floor → GridBound (Tier1:occupancy × load_balance) + │ perfbound/model/grid_model.py:47 + └─ classify_handoffs → SerializationSplit (强制/可避免 serial 拆分) + │ perfbound/model/serialization.py + └─ combine(grid, comp, serial) perfbound/combine/bound_combiner.py:114 + → BoundResult.t_bound_us = max(t_grid_floor, t_core_floor + t_serial_irreducible) + + Attribution(grid + gap1..gap4) perfbound/combine/bound_combiner.py:45 + └─ compute_two_limit perfbound/combine/two_limit.py:161 + → TwoLimitResult(t_bound_hivm, t_bound_dsl, t_measured) + headroom + perfbound/combine/two_limit.py:35 +``` + +一键入口:`bound_from_extract()`(`perfbound/combine/bound_combiner.py:201`),自动加载 +默认 910B3 校准(`load_default_calib_db`),从一个 `HIVMExtract` 直接得到 `BoundResult`。 + +### 它确实产出 bound 的证据 + +- `T_bound = max(T_grid_floor, T_core_floor + T_serial_irreducible)`: + `bound_combiner.py:153-154`(注意是 `max(a, b+c)` 而非 `max(a,b)+c`,A.5 守恒性修正)。 +- 两层来源:Tier1 grid floor + Tier2 component floor(调和均值 ideal `I_c`)+ 强制 serial。 +- 双下界:`T_bound_HIVM` vs `T_bound_DSL`,差值 = 编译器 headroom(`two_limit.py:45-52`)。 + +### 覆盖测试 + +`tests/perfbound/test_bounds.py`、`test_combine.py`、`test_two_limit.py`、 +`test_calibration_wiring.py`、`test_component_model.py`。 + +> 这部分是 master 原有的,**不是**本次 cherry-pick 带来的。 + +--- + +## B. PR#17 的 C++ `HIVMBottleneckDiagnoser` —— 是「诊断」,不是「bound」 + +### 接入点(已 wire 进 CLI) + +``` +HIVMAnalysis.cpp:3295 HIVMBottleneckDiagnoser diagnoser(config); +HIVMAnalysis.cpp:3296 diagnoser.diagnose(report, report.bottleneckReport); +tritonsim-hivm.cpp:606 report.bottleneckReport.print(llvm::outs(), getHardwareConfig()); +``` + +### 它算什么 + +- **每 op 的 `theoreticalMinCycles`**(局部弱下界)+ `overheadRatio`: + `HIVMBottleneckDiagnosis.cpp:52` `computeTheoreticalMin()`—— + 传输 op = `ceil(bytes / 带宽)`;Vector = `startup + ceil(elements / 向量宽)`;Cube/FixPipe 类似。 +- **6 类根因分类** `BottleneckType`(`HIVMBottleneckDiagnosis.h:27`): + `BandwidthBound, ComputeBound, StartupOverhead, SyncOverhead, PipelineImbalance, LowParallelism`。 + 逐 op:`diagnoseOp`(`.cpp:94`);流水:`diagnosePipeline`(`.cpp:267`,imbalanceRatio>3 判 + PipelineImbalance);全局:`diagnoseGlobal`。 +- **文字 suggestions** + `syncOverheadRatio` / `barrierOverheadRatio`(`HIVMBottleneckReport`,`.h:59`)。 + +### 它**不**算什么(= 它不是 bound 的原因) + +- ❌ 无 kernel 级 `max(T_grid, T_core + T_serial)`; +- ❌ 无 Tier-1 grid(occupancy / load_balance); +- ❌ 无 component 级调和均值 `I_c`、无按 component 聚合对比 sustained 速率 + (per-op `theoreticalMinCycles` 之和 ≠ component floor——没有重叠/并行模型); +- ❌ 无 强制/可避免 serial 拆分; +- ❌ 无 HIVM-vs-DSL 双下界 / headroom。 + +一句话:**PR#17 = 「IR 时刻、从 HIVM 调度结果直接做根因分类 + 给优化建议」的诊断器。** + +--- + +## C. 关键发现:重复 + 断裂 + +### C.1 重复(两套 5 类分类) + +| | 输入口径 | 实现 | +|---|---------|------| +| **B(C++,PR#17)** | 分析调度得到的 theoMin / overhead | `HIVMBottleneckDiagnoser::diagnose` | +| **B′(Python)** | 实测 / realized 的 A/I/U/R/E | `analyze_operator_bottleneck`(`profile_utilization.py:235`) | + +**同一套 5 类瓶颈分类的两个实现**(B 多一个 `LowParallelism`;B′ 另有「暴露控制/同步赤字」A.8 量化)。 +两边各活各的,口径未统一。 + +### C.2 断裂(诊断 ↔ bound 未连) + +- PR#17 的 C++ 诊断器**不**喂给 Python 的 bound; +- Python 的 bound **不**读 PR#17 的诊断; +- C++ 这边能出诊断但出不了 `T_bound`;Python 那边能出 `T_bound` 但跑在另一条 subprocess 链上。 + +### C.3 与优化手册的对应关系 + +PR#17 `diagnoseOp` 里的 suggestion 文字—— +- "Replace PIPE_ALL barrier with per-pipe set_flag/wait_flag"(`.cpp:131`) +- "Increase tile size to amortize startup latency"(`.cpp:162/212`) +- "Increase K tile dimension to improve arithmetic intensity"(`.cpp:227`) +- "Consider Cube-Vector split to exploit dual-core parallelism"(`.cpp:323`) + +**逐条就是** `hivm_optimization_playbook.md` §3–§7 的 21 条手段。三者的分工因此清晰: + +``` +PR#17 HIVMBottleneckDiagnoser = 检测 + 建议引擎(C++,IR 时刻) +playbook hivm_optimization = HIVM 重写规范(手段 → before/after IR) +perfbound bound_from_extract = 量化 bound(改写前后各算一次,验证收敛) + ▲ 缺:执行器(把建议真正改成优化后 HIVM 的 edit 原语) + 三者串联 +``` + +--- + +## D. 结论与下一步 + +**结论**: +1. 「基于 HIVM 出解析 bound」——**已经有了**,是 Python `perfbound`(`bound_from_extract` / + `compute_bounds` / `combine` / `two_limit`),master 原有、有测试。 +2. PR#17 的价值是**补上了 C++ 侧 IR 时刻的根因诊断 + 优化建议**,对接优化目标,但**不产出 bound 数值**。 +3. 现状是「诊断(B/B′)」与「bound(A)」两套独立体系,且 B 与 B′ 口径重复。 + +**若要做「诊断 → bound → 输出优化后 HIVM」闭环,建议顺序**: +1. **统一口径**:让 PR#17 的 `BottleneckType` 对齐 Python 五轴 gap(grid + gap1–4),避免两套标准。 +2. **建执行器**:实现 `playbook` 里待建的 HIVM edit 原语(`barrier_to_p2p`、`reorder_independent`、 + `prefetch_to_l1`、`enlarge_tile`、`cube_vector_split`),对齐现有 `perfbound/validate/hivm_edits.py` + 的 source-to-source + no-op guard 风格。 +3. **闭环验证**:改写前后各跑一次 `bound_from_extract` 比较 `T_bound`—— + (A) 缩小 gap 类应保持 `T_bound` 不变、关键路径下降;(B) 降低 bound 类应 `T_bound` 下移且守住 + `T_bound ≤ T_measured`(见 `playbook` §8 判读规则)。 + +--- + +## 附:核心证据索引(file:line) + +| 主题 | 位置 | +|------|------| +| T_bound 公式 `max(grid, core+serial)` | `perfbound/combine/bound_combiner.py:153` | +| 一键入口 `bound_from_extract` | `perfbound/combine/bound_combiner.py:201` | +| 两层 bound 组装 `compute_bounds` | `perfbound/model/bounds.py:44` | +| Tier2 component floor / I_c | `perfbound/model/component_model.py:164` | +| Tier1 grid floor | `perfbound/model/grid_model.py:47` | +| 双下界 / headroom | `perfbound/combine/two_limit.py:35,161` | +| HIVM→extract runner | `perfbound/extract/hivm_runner.py:41` | +| PR#17 诊断接入 | `lib/AscendModel/Analysis/HIVMAnalysis.cpp:3295` | +| PR#17 诊断打印 | `tools/tritonsim-hivm/tritonsim-hivm.cpp:606` | +| PR#17 per-op theoMin | `lib/AscendModel/Analysis/HIVMBottleneckDiagnosis.cpp:52` | +| PR#17 BottleneckType(5+1) | `include/AscendModel/Analysis/HIVMBottleneckDiagnosis.h:27` | +| Python 同款诊断(重复) | `perfbound/analyze/profile_utilization.py:235` | +| 优化手段 ↔ HIVM 重写 | `hivm_optimization_playbook.md`(同目录) | diff --git a/docs/hivm_bound_rewrite/hivm_optimization_playbook.md b/docs/hivm_bound_rewrite/hivm_optimization_playbook.md new file mode 100644 index 0000000..bc22977 --- /dev/null +++ b/docs/hivm_bound_rewrite/hivm_optimization_playbook.md @@ -0,0 +1,558 @@ +# HIVM 优化手册:从性能问题到「优化后 HIVM」 + +> 目标:把 5 类常见性能问题的 21 条常规优化手段,逐条落到 **HIVM 层面**—— +> 给出「检测信号 → HIVM 变换 → before/after IR → 对模型量的影响 → 落地与合法性」, +> 最终产出**优化后的 HIVM**(`.npuir.mlir` HIR,并以 DES-graph JSON 作为模型可消费/可验证的投影)。 + +本手册与 `.omc/specs/performance_bound_model.md` 的两层上界模型、以及 `perfbound/` +归因管线严格对齐:每条手段都标注它**缩小哪个 gap** 或**降低哪个 floor**。 + +--- + +## 0. 两个 HIVM 工件,先分清 + +「优化后的 HIVM」存在两种表示,本手册始终区分: + +| 工件 | 形态 | 谁产生 / 谁消费 | 本手册的角色 | +|------|------|----------------|--------------| +| **HIVM HIR** | `.npuir.mlir` 文本(`hivm.*` op,MLIR `ModuleOp`) | bishengir 编译产出 / 人工 author;`tritonsim-hivm --npuir-file` 消费;**`HivmOpsEditor`(C++)加载/改写/导出** | **优化的真正落点**——重写它 = 输出优化后 HIVM | +| **DES-graph JSON** | `a3_hivm_des_v1`(`operations[]`) | `emitDESGraph()`(C++)产出;`perfbound` 模型 + `validate/hivm_edits.py` 消费 | 模型分析投影 + counterfactual 验证介质 | + +> **代码更新(PR#20/#17 已合入 `integrate/pr20-pr17`)后的关键变化**:HIR 的「执行器」已经**不再是 +> 待建**——PR#20 引入了 MLIR 原生的 **`HivmOpsEditor`**(`include/AscendModel/Transforms/HivmOpsEditor.h`) +> 与 CLI **`hivm-crud`**,能 `loadFromFile(.npuir.mlir.bak)` → 改写 `hivm.*` op → `exportToFile(.npuir.mlir)`, +> **直接产出优化后 HIVM HIR**。它内置了本手册多条手段的现成原语(见 §9 重写后的现状表)。 +> 注意:`HivmOpsEditor` 整体受 `#ifdef TRITONSIM_HAS_BISHENGIR_HIVM` 保护,需启用 bishengir HIVM 方言才编译。 + +一条优化的完整闭环(两条实现线交汇,§2.5 有更完整的版本): + +```mermaid +flowchart TD + DET["检测
C++: HIVMBottleneckDiagnoser (IR 时刻, 5 类+建议)
Python: profile_utilization (实测口径 A/I/U/R/E)"] + BAK[".npuir.mlir (.bak)"] + OPT["优化后 .npuir.mlir
← 输出优化后 HIVM"] + DESJ["DES-graph JSON"] + BND["HIVMExtract → perfbound
T_bound / gap / 双下界"] + CFV["counterfactual 对比 (改写前后 T_bound)
perfbound/validate: counterfactual + hivm_edits"] + DET --> BAK + BAK -->|"HivmOpsEditor (C++) 改写"| OPT + OPT -->|"同一文件再次导出 DES-graph"| DESJ + DESJ --> BND + BND --> CFV +``` + +两条线的分工: +- **C++(IR 原生线)**:调度 + 诊断(`HIVMBottleneckDiagnoser`)+ **HIR 改写/导出(`HivmOpsEditor`/`hivm-crud`)**—— + 真正「输出优化后 HIVM」的执行器。 +- **Python(解析模型线)**:消费 DES-graph JSON → 算 `T_bound`/gap/双下界(`perfbound`); + `validate/hivm_edits.py` 在 **JSON 投影**上做 source-to-source 编辑(`raise_repeat`/`insert_pingpong`/ + `merge_transfers`),作为不需要 bishengir 即可跑的 counterfactual 快速代理。 + +二者共享下面的重写词汇表,并在 DES-graph JSON 这一契约上交汇。 + +--- + +## 1. HIVM 重写词汇表(变换的最小操作集) + +来自 `test/hivm_mixed_cv_kernel.npuir.mlir` / `hivm_add_kernel.npuir.mlir` 与 +`include/AscendModel/Analysis/HIVMAnalysis.h::HIVMOp`。 + +### 1.1 算子(HIR op) + +| HIR op | 流水 (pipe) | 语义 | src→dst space | +|--------|------------|------|---------------| +| `hivm.hir.load` | `PIPE_MTE2` | GM→UB 搬入 | gm→ub | +| `hivm.hir.store` | `PIPE_MTE3` | UB→GM 搬出 | ub→gm | +| `hivm.hir.nd2nz` | `CubeMTE2` | GM→L1 布局转换搬入(cube 路径,≈0.5×带宽) | gm→cbuf(l1) | +| `hivm.hir.mmadL1` | `PIPE_M`(Cube)/`MTE1` | L1→L0A/B + 矩阵乘 | cbuf→cc(l0c) | +| `hivm.hir.fixpipe` | `PIPE_FIX` | L0C→UB 回写/量化 | cc→ub | +| `hivm.hir.vadd`/`vmul`/… | `PIPE_V`(Vector) | UB 内逐元素计算 | ub→ub | +| `hivm.hir.pointer_cast` | — | 在某 space 分配 buffer(含 multi-buffer slot) | — | + +### 1.2 同步原语(这是 SyncOverhead 一类的主战场) + +```mlir +// 点对点(per-pipe)信号:生产 pipe SRC 通知消费 pipe DST,事件号 EVENT +hivm.hir.set_flag [, , ] +hivm.hir.wait_flag[, , ] + +// 全局屏障:所有 pipe / 跨核全停等 +hivm.hir.pipe_barrier[] +``` + +- 一对 `set_flag/wait_flag` ⇒ DES 中 `is_sync=true`、`event_id`、`event_generation`、 + `sender_pipe`、`receiver_pipe`。DES 调度按 `(event_id, generation, source_core)` 配对, + 支持 AIC↔AIV 跨核(见 `mixed_cv` 中 `PIPE_M→PIPE_FIX→PIPE_V` 链)。 +- `pipe_barrier[]` ⇒ `is_barrier=true`,计入 `barrier_cycles`,让**所有** pipe + 在该点对齐——这是同步开销的主要来源。 + +### 1.3 可改写的 HIVMOp 字段(DES-graph 侧,模型直接读) + +`id, pipe, depends_on[], is_sync, is_barrier, event_id, event_generation, +sender_pipe, receiver_pipe, core_type, bytes, elements, flops, loop_multiplier, +multi_buffer_slots, read_buffers[]/write_buffers[], read_versions[]/write_versions[], +src_space, dst_space, elem_type, repeat, mask` + +> 关键映射:`repeat/mask`→Gap4;`bytes`+`src/dst_space`→MTE floor & Gap2; +> `is_barrier`/`is_sync`/`event_*`→同步开销 & Gap3;`multi_buffer_slots`+`*_versions`→ +> 流水重叠 & Gap3;`core_type`→Tier-1 双核/负载均衡;`flops`+tile 维→Compute floor。 + +--- + +## 2. 问题类 ↔ 模型五轴 gap 映射(总表) + +模型把「与上界的距离」分解为 5 轴(grid + 4 gap),并区分**两种优化**: +**(A) 缩小 gap**——不改变 `T_bound`,让实测向下界收敛(调度/同步/buffer 类); +**(B) 降低 bound**——改变计算量/流量,`T_bound` 本身下移(tiling/fusion/降流量类)。 +### 五轴 gap 表 + +| Gap 类别 | 问题来源 | 典型表现 / 原因 | 优化方向 | +|---------|----------|----------------|----------| +| grid | 线程网格/工作组划分不合理 | 硬件占用率不足(occupancy 低);各处理单元负载不均衡 | 调整 grid/block 尺寸、优化任务分配策略,充分利用计算资源 | +| gap1 | 错误单元放置(算子分配到次优硬件单元) | 本该跑在 Cube 的矩阵运算被放到了 Vector 单元;单元选择与算子特性不匹配 | 改进算子映射 cost model;手工引导调度,让计算密集部分使用最强算力单元 | +| gap2 | 合并/传输效率低(MTE、DMA 等) | 小包传输无法摊平开销;地址未对齐;未用满突发传输能力 | 合并小传输、数据对齐、增大 burst 长度、利用 MTE2 预取 | +| gap3 | 可避免的串行化(生产-消费 handoff) | 通过 ping‑pong buffer 或软件流水可消除的同步等待,属于 `T_serial` 中可优化的部分 | 引入多缓冲/双缓冲/软件流水线,重叠执行,消除显式等待点 | +| gap4 | 单元内执行效率低(SIMD / 矩阵引擎) | SIMD 通道利用率低(向量长度不足、掩蔽浪费);矩阵 K 维度未填满硬件流水 | 合并向量运算、增大 tile 尺寸、调整循环次数以匹配 SIMD 宽度或 Cube 的 K 维度 | + +| bound归因分类 | 主导模型量 | 对应 gap 轴 | 论文 fix | 优化性质 | +|-----------------------|-----------|-------------|----------|----------| +| **SyncOverhead** | `barrier_cycles` / 暴露控制 / Gap3 | Gap3(R 轴,MTE/控制) | RUS, PP, RSD, AIS-reorder | 主要 (A) | +| **BandwidthBound** | MTE-GM floor / Gap2 / Gap3 | Gap2(E轴)+Gap3(R轴)+floor | ITG, MRT, TT, PP | (A)+(B) | +| **StartupOverhead** | per-op 启动延迟(E 轴) | Gap2 / Gap4 startup 分量 | ITG, AIP, OP-fusion | (A) 偏 (B) | +| **ComputeBound** | Cube/Vector floor / Gap4 | 多为 floor(非 gap)+ Gap4 | EA, AIP, OP-fusion | 主要 (B) | +| **PipelineImbalance** | Tier-2 重叠 / cv-balance / Tier-1 | Gap3 + grid | PP, Cube-Vector split | (A) | + +> 注意一个论文级判断:当某 component 利用率已逼近其 ideal(如 ComputeBound 的纯算力打满), +> **那不是 gap**——只能靠 (B) 降低 bound(增大算术强度、融合、降精度),不能靠调度收敛。 +> 本手册对每条手段都标注 (A)/(B)。 + +--- + +## 2.5 两条实现线:C++(IR 原生)与 Python(解析模型) + +代码现状里,「检测 → 改写 → 验证」分布在两条独立、在 **DES-graph JSON** 处交汇的实现线上。 +理清这两条线,才能知道每条手段「在哪写、用什么写、怎么验」。 + +### C++ 线(IR 原生:调度 / 诊断 / 改写) + +| 角色 | 符号 / 工具 | 文件 | 职责 | +|------|------------|------|------| +| 调度分析 | `HIVMAnalyzer` | `lib/AscendModel/Analysis/HIVMAnalysis.cpp` | 解析 `.npuir.mlir`,分流水调度,导出 DES-graph JSON / Perfetto | +| **诊断** | `HIVMBottleneckDiagnoser` | `lib/AscendModel/Analysis/HIVMBottleneckDiagnosis.cpp` | 从调度结果分类 6 类瓶颈(= 你的 5 类 + LowParallelism)+ 给 suggestions | +| **改写(执行器)** | `HivmOpsEditor` | `include/AscendModel/Transforms/HivmOpsEditor.h` | MLIR 原生 CRUD:load `.bak` → 改 `hivm.*` op → export `.npuir.mlir` | +| CLI | `hivm-crud` | `tools/hivm-crud/hivm-crud.cpp` | `--mode read/add/delete/modify/roundtrip`、`--remove-gm-trips N` 的薄封装 | + +C++ 线**直接操作真实 HIR**,是「输出优化后 HIVM」的落点。诊断与改写都在 IR 时刻(无需实测)。 + +### Python 线(解析模型:bound / 归因 / counterfactual) + +| 角色 | 符号 | 文件 | 职责 | +|------|------|------|------| +| 提取 | `extract_from_npuir` / `extract_hivm` | `perfbound/extract/hivm_runner.py`、`hivm_extractor.py` | 调 C++ 工具导出 DES-graph JSON → `HIVMExtract` | +| **bound** | `compute_bounds` / `combine` | `perfbound/model/bounds.py`、`perfbound/combine/bound_combiner.py` | 两层 `T_bound = max(grid, core+serial)` + 5 轴归因 | +| 双下界 | `compute_two_limit` | `perfbound/combine/two_limit.py` | `T_bound_HIVM` vs `T_bound_DSL` + headroom | +| 诊断(实测口径) | `analyze_operator_bottleneck` | `perfbound/analyze/profile_utilization.py` | 与 C++ 诊断同套 5 类,但从实测 A/I/U/R/E 判 | +| counterfactual | `hivm_edits` / `counterfactual` | `perfbound/validate/*.py` | 在 **JSON 投影**上做代理编辑,不需 bishengir | + +Python 线**不碰 HIR**,只消费 C++ 导出的 JSON 算量化 bound,并以 JSON 编辑做快速 counterfactual。 + +### 两线交汇 = 优化闭环(mermaid) + +```mermaid +flowchart TD + subgraph SRC["源"] + DSL["Triton DSL .py"] + NPUIR[".npuir.mlir (HIVM HIR)"] + end + DSL -->|"launcher compile-only dump"| NPUIR + + subgraph CPP["C++ 线 — IR 原生 (tritonsim-hivm)"] + ANA["HIVMAnalyzer
分流水调度"] + DIAG["HIVMBottleneckDiagnoser
6 类瓶颈 + suggestions"] + EDIT["HivmOpsEditor / hivm-crud
load→改写 hivm.* op→export"] + DES["DES-graph JSON
(a3_hivm_des_v1)"] + PERF["Perfetto trace"] + ANA --> DES + ANA --> PERF + ANA --> DIAG + end + NPUIR --> ANA + + subgraph PY["Python 线 — 解析模型 (perfbound)"] + EXT["extract_hivm → HIVMExtract"] + COMP["compute_component_floor (Tier2)
compute_grid_floor (Tier1)
classify_handoffs (serial)"] + BND["combine → BoundResult
T_bound = max(grid, core+serial)
+ 5 轴 gap 归因"] + TWO["compute_two_limit
T_bound_HIVM / DSL + headroom"] + PROF["profile_utilization
实测 A/I/U/R/E (诊断, 同 5 类)"] + CF["validate/hivm_edits
JSON 投影 counterfactual"] + EXT --> COMP --> BND --> TWO + end + DES --> EXT + DES -.JSON 代理编辑.-> CF + + %% 诊断驱动改写 + DIAG -->|"suggestion → 选手段 (§3–§7)"| EDIT + PROF -.实测口径诊断.-> EDIT + BND -.gap 归因.-> EDIT + + %% 执行器产出优化后 HIVM,回灌闭环 + EDIT ==>|"输出优化后 .npuir.mlir"| NPUIR2[".npuir.mlir (优化后)"] + NPUIR2 -->|"再次 tritonsim-hivm"| ANA + + %% 验证:改写前后比较 + BND --> VERDICT{"(A) gap 收敛: T_bound 不变
(B) 降 bound: T_bound 下移
且 T_bound ≤ T_measured"} + CF --> VERDICT +``` + +> 关键点:诊断(C++ `HIVMBottleneckDiagnoser` / Python `profile_utilization`)给出**手段选择**, +> C++ `HivmOpsEditor` 执行**HIR 改写**并产出优化后 `.npuir.mlir`,Python `perfbound` 在改写前后各算一次 +> `T_bound` 做**收敛验证**。三段恰好是「诊断—执行—度量」,分属两条线但闭环。 + +--- + +## 3. SyncOverhead — 同步开销(主战场:set_flag/wait_flag、pipe_barrier) + +检测信号:DES 报告 `barrier_cycles` 占比高;关键路径上 `wait_flag` 的 `start_cycle` +远晚于其匹配 `set_flag` 的 `end_cycle`(暴露的 stall);A.8 暴露控制/同步赤字 +(`exposed_control_deficit_*`)为正。 + +### ① `pipe_barrier` → per-pipe `set_flag/wait_flag` —— (A) 缩小 Gap3(RUS) + +把粗粒度全局屏障替换为只约束真实生产者/消费者 pipe 的点对点信号,让无关 pipe 继续跑。 + +**before**(vadd 之后用全局屏障保护 store): +```mlir +hivm.hir.vadd ... outs(%ub2 : ...ub>) // PIPE_V 写 %ub2 +hivm.hir.pipe_barrier[] // ★ 所有 pipe 全停 +hivm.hir.store ins(%ub2 ...) outs(%dst ...) // PIPE_MTE3 读 %ub2 +``` +**after**: +```mlir +hivm.hir.vadd ... outs(%ub2 : ...ub>) +hivm.hir.set_flag [, , ] // 仅 V→MTE3 +hivm.hir.wait_flag[, , ] +hivm.hir.store ins(%ub2 ...) outs(%dst ...) +``` +DES 影响:`is_barrier` 项消失,`barrier_cycles`↓;其它核/pipe(如下一 tile 的 MTE2 load) +不再被这点拉平 → 关键路径缩短,Gap3↓。**合法性**:仅当 barrier 的全部跨 pipe 顺序约束 +都被新插入的 set/wait 边覆盖时才合法(否则引入 race)——重写器须用 `read/write_buffers` ++`*_versions` 的 RAW/WAR 依赖证明覆盖完整。 + +### ② multi-buffer pipelining 降低屏障频率 —— (A) 缩小 Gap3(PP/RSD) + +把每轮迭代结尾的屏障,换成「双 slot + 版本轮换」,使第 i+1 轮 load 不必等第 i 轮消费完。 + +HIVM 变换:`pointer_cast` 分配 2 个 slot(`multi_buffer_slots: 2`);偶/奇迭代交替写 +`write_versions=[v]`、读 `read_versions=[v-1]`;屏障从内层移到外层(频率 1/2)。 +DES 影响:producer/consumer 跨迭代重叠,关键路径中 MTE 被 compute 覆盖。 +**落地**:现有 `insert_pingpong()` 在 DES-graph 上以「复制 MTE_UB op」近似此效果;HIR 级 +需真正分配双 buffer 并改版本号。 + +### ③ reorder ops 减少 wait stall —— (A) 缩小 Gap3(AIS-reorder) + +在 `set_flag` 与 `wait_flag` 之间塞入与该事件无关的独立 op,使 `wait_flag` 到达时信号已就绪。 + +**before**(load 之后立刻 wait,stall 暴露): +```mlir +hivm.hir.load %src0 -> %ub0 +hivm.hir.set_flag [,,] +hivm.hir.wait_flag[,,] // V 在此干等 load +hivm.hir.vadd %ub0,%ub1 -> %ub2 +``` +**after**(把第二个独立 load 提前到 wait 前,填满等待窗口): +```mlir +hivm.hir.load %src0 -> %ub0 +hivm.hir.load %src1 -> %ub1 // ← 独立 load 上移,占住 V 等待时间 +hivm.hir.set_flag [,,] +hivm.hir.wait_flag[,,] +hivm.hir.vadd %ub0,%ub1 -> %ub2 +``` +DES 影响:`wait_flag.start_cycle` 不变但其后续 compute 的暴露等待被独立 work 吸收,关键路径↓。 +**合法性**:被移动 op 与跨越区间内所有 op 无 buffer 依赖(用 `depends_on`/版本验证)。 + +### ④ 全局:减少全局屏障,用 per-pipe sync —— (A) 缩小 Gap3(RUS,①的全局化) + +扫描整个 kernel,删除「其顺序已被既有 set/wait 边蕴含」的冗余 `pipe_barrier[]`。 +判定:对每个 barrier,若它分隔的每一对真实依赖 (producer_pipe,consumer_pipe) 都已存在 +匹配的 set/wait(或可安全补一条点对点边),则该 barrier 冗余可删。模型影响同①,作用于全核。 + +### ⑤ 全局:多 buffer 解耦 producer/consumer —— (A) 缩小 Gap3(PP,②的结构化) + +对整条 producer→consumer 链做结构化双/多缓冲(depth≥2),使两端完全解耦、稳态下各自打满。 +HIVM 变换:链上每个中间 buffer 升为 N-slot,`multi_buffer_slots=N`,版本轮换;sync 退化为 +环形依赖。模型影响:Tier-2 中两 component 从「串行相加」变「max 并行」,`T_serial` 仅剩首/尾 +填充,Gap3 趋零。 + +--- + +## 4. BandwidthBound — 带宽受限(主导:MTE-GM floor + Gap2/Gap3) + +检测信号:`binding_component == MTE_GM`,其 `U` 高而 compute `U` 低;或 Gap2(合并/对齐) +分量大。 + +### ① 减少数据搬运(in-place / tiling reuse) —— (B) 降低 MTE floor(MRT) + +消除「已驻留 UB/L1 的算子重复 load」,或就地计算。`mixed_cv` 已示范就地:`vadd ins(%cv_ub,%cv_ub) outs(%cv_ub)`。 + +**before**(重复从 GM 读同一 operand): +```mlir +hivm.hir.load %gm_x -> %ub_a // tile i +... +hivm.hir.load %gm_x -> %ub_a2 // tile i+1 又读同一 %gm_x ← 冗余 GM 流量 +``` +**after**(识别 `read_buffers` 同根 + 版本未变 → 删除第二次 load,复用 buffer): +```mlir +hivm.hir.load %gm_x -> %ub_a // 只读一次,后续复用 %ub_a +``` +模型影响:`bytes`(MTE_GM)↓ → `O_mte_gm/I_mte_gm` floor 直接下移,**T_bound 本身下降**。 +**落地**:DES-graph 上删冗余 MTE op;HIR 上删 `load` 并把消费者的 operand 改指向驻留 buffer。 + +### ② 传输与计算重叠(multi-buffer) —— (A) 缩小 Gap3 + +不减字节,但把 tile i+1 的 `load`(MTE2) 与 tile i 的 `vadd/mmad`(V/Cube) 重叠。机制同 §3②⑤。 +模型影响:MTE-GM 退出关键路径(被 compute 覆盖),实测向 `max(MTE,Compute)` 收敛。 + +### ③ CubeMTE2 专有:提前 prefetch 到 L1 —— (A) 缩小 Gap3(TT/PP) + +把 `nd2nz`(GM→L1/cbuf)提前到 mmad 之前若干步发射,沿 CubeMTE2 流水预取,隐藏 MTE1 输入等待。 + +**before**: +```mlir +hivm.hir.nd2nz %gm_a -> %a_l1 // 紧贴 mmad +hivm.hir.mmadL1 %a_l1,%b_l1 -> %c_l0c +``` +**after**(prefetch 下一片 a,与当前 mmad 重叠): +```mlir +hivm.hir.nd2nz %gm_a_next -> %a_l1_slot1 // ← 预取,发射提前 +hivm.hir.mmadL1 %a_l1_slot0,%b_l1 -> %c_l0c +``` +模型影响:CubeMTE2/MTE1 传输被 Cube 计算覆盖,Gap3↓。`src_space=gm,dst_space=cbuf` 不变。 + +### ④ 全局:减少总数据量 / 提高 tile reuse —— (B) 降低 floor(EA) + +通过更大 tile 或循环重排提升 operand 复用,减少跨 tile 的 GM 重读(对应 Tier-1 `redundancy` +与 Tier-2 `bytes_in`)。模型影响:`bytes`↓ → MTE-GM floor↓,T_bound↓。属算法/tiling 轴。 + +### ⑤ 全局:software pipelining 重叠传输与计算 —— (A) 缩小 Gap3(②③的结构化) + +整 kernel 软件流水(prologue/steady/epilogue),稳态下 MTE 与 Compute 完全重叠。模型影响同 §3⑤。 + +--- + +## 5. StartupOverhead — 启动开销(E 轴:每 op 固定启动延迟) + +检测信号:op 数量多、单 op `bytes/elements` 小;DES 中传输/compute 的 `duration` 里启动占比高 +(C++ 侧 `estimateND2NZCycles`/vector startup 的 `startupCycles` 分量)。 + +### ① 增大 tile size 摊薄 startup —— (B)→(A) 边界,降 E 轴损失(ITG) + +每个 `load/nd2nz/vadd` 有固定 startup;tile 越大,startup 占比越小。 +HIVM 变换:把 `memref<128x128>` 类形状放大到 `256x256`,相应 `loop_multiplier`↓、op 数↓。 +模型影响:有效带宽/吞吐 E↑(`actual/ideal` 上升),Gap2/Gap4 的 startup 分量↓。 +**约束**:受 L0/L1/UB 容量限制(`UnifiedTilingCostModel` 的 buffer check)——放大须过 buffer 约束。 + +### ② 融合相邻传输,减少 per-transfer overhead —— (A) 缩小 Gap2(ITG) + +合并 `src_space/dst_space` 相同的相邻 `load`/`nd2nz` 为一次大传输:一次 startup 代替 N 次。 + +**before** → **after**: +```mlir +hivm.hir.load %gm_x0 -> %ub0 hivm.hir.load %gm_x01 -> %ub01 // 合并:bytes 求和, +hivm.hir.load %gm_x1 -> %ub1 ⇒ // 一次 startup(src/dst space 相同且地址连续才合法) +``` +**落地**:现有 `merge_transfers()` 已实现此变换(DES-graph 上对相邻同 space MTE_GM 求和 bytes)。 +模型影响:MTE op 数↓、总 startup↓ → Gap2↓。 + +### ③ 融合相邻 vector ops,减少 launch overhead —— (A)/(B) 缩小 Gap4 + 降 sync + +把 UB 内相邻 `vadd→vmul→…` 融成一条向量指令链,省去中间 op 的 startup 与可能的 set/wait。 + +**before**: +```mlir +hivm.hir.vmul %ub_a,%ub_b -> %ub_t // 启动+计算 +hivm.hir.vadd %ub_t,%ub_c -> %ub_o // 又一次启动 +``` +**after**(融合为一条 fma 链,单启动): +```mlir +hivm.hir.vfma %ub_a,%ub_b,%ub_c -> %ub_o +``` +模型影响:vector op 数↓、`repeat` 可提升(Gap4 改善)、潜在 sync 边减少。 + +--- + +## 6. ComputeBound — 计算受限(多为 floor,需 (B);Gap4 是唯一 (A)) + +检测信号:`binding_component ∈ {Cube, Vector}` 且其 `U ≥ u_threshold`(已逼近 roofline)。 +此时**不是 gap**——纯调度收敛无效,须降低 bound 或修 Gap4 执行效率。 + +### ① Cube 专有:增大 K 维提高算术强度 —— (B) 降低 Cube floor(EA) + +`mmadL1 ins(%a_l1,%b_l1,%true,%M,%N,%K)` 的 K(第 6 个 index 参数)增大:MTE1 搬入的 L1 +输入被更多 MAC 复用,FLOP/byte↑。 +模型影响:`flops`↑相对 `bytes` 更快 → Cube 成为 binding 时算术强度上升、roofline ridge 右移, +单位时间有效算力↑,等效 T_bound↓。属算法轴。 + +### ② Vector 专有:融合相邻 vector ops —— (A) 缩小 Gap4 + +同 §5③。当 Vector binding 且 `repeat=1`/`mask` 浪费 lane 时收益最大(论文 AvgPool 案例: +`repeat=1` 强制 98 次循环,一次 AIP→4.31×)。 +HIVM 变换:提高 `repeat`、清零 `mask`(启用全 lane)。**落地**:现有 `raise_repeat()` 在 +DES-graph 上把 compute op 的 `repeat *= factor`,正是此轴的 counterfactual。 + +### ③ 与 MTE2 prefetch 重叠 —— (A) 缩小 Gap3 + +同 §4③,把输入搬运藏到 Cube/Vector 计算之下,使 compute 真正连续打满。 + +### ④ 全局:增大 K/M/N tiles —— (B) 降低 floor + +更大 tile 同时提升算术强度与摊薄 startup(§5①ר6①的综合)。受 buffer 容量约束。 + +### ⑤ 全局:op 融合减少 launch+sync 开销 —— (B)/(A) + +跨算子融合(如 MatMul→Softmax 链内保留中间结果在片上),减少 GM 往返 + sync。 +模型影响:既降 `bytes`(floor↓)又减 `T_serial` 的强制 handoff(§2 的「不是 gap → 降 bound」轴)。 + +--- + +## 7. PipelineImbalance — 流水不均衡(Tier-2 重叠 + Tier-1 双核) + +检测信号:DES 中某 pipe `busy_cycles` 高、其它 pipe 大量 idle;`cvBalanceRatio = min(C,V)/max(C,V)` +远小于 1;或 Tier-1 `load_balance` 低。 + +### ① 多 buffer pipelining 重叠 busy/idle pipe —— (A) 缩小 Gap3 + +用双/多缓冲让 idle pipe 提前做下一 tile 的工作,填满它在当前 tile 的空窗。机制同 §3②⑤。 +模型影响:各 pipe `R`(residency)趋齐,关键路径从「串行之和」降到「max」。 + +### ② Cube-Vector split 利用双核并行 —— (A) Tier-1/Tier-2 联动 + +把可分离的 Cube 工作与 Vector 工作分派到 AIC / AIV 两核(`core_type` = CUBE/AIC vs VECTOR/AIV), +用跨核 `set_flag/wait_flag` 衔接——`mixed_cv` fixture 的 `PIPE_M→PIPE_FIX→PIPE_V` 正是此结构。 +HIVM 变换:给 op 标 `core_type`,在 AIC 段末/AIV 段首插跨核事件对(DES 按 source_core 配对)。 +模型影响:两核并行 → busiest-core work↓,Tier-1 `load_balance`↑、Tier-2 重叠↑。 + +### ③ 增加 pipeline depth 填充 idle slots —— (A) 缩小 Gap3 + +把缓冲深度 depth 从 2 提到 3+,覆盖更长的 producer/consumer 延迟差,进一步压平 idle。 +约束:depth × tile 须过 buffer 容量检查;超深度收益递减。 + +--- + +## 8. 产出「优化后 HIVM」与验证闭环 + +每条手段的产出都要经过同一闭环证明「确实更快、且 bound 未被违反」。代码更新后, +**第 1 步已有真实执行器**(C++ `HivmOpsEditor`),不再只能手改或走 JSON 代理。 + +生产路径的 HIR 改写工作流(`HivmOpsEditor`,需 `TRITONSIM_HAS_BISHENGIR_HIVM`): + +```mermaid +flowchart LR + L["loadFromFile
kernel.npuir.mlir.bak"] + P["调用相应原语 (见 §9)
addSetFlagWaitFlag* / insertDoubleBuffering /
fuseConsecutiveComputeOps /
removeRedundantLoadStorePair / changeShape …"] + E["exportToFile
kernel.opt.npuir.mlir
← 输出优化后 HIVM"] + L --> P --> E +``` + +等价 CLI:`hivm-crud --input k.npuir.mlir.bak --output k.opt.npuir.mlir --mode roundtrip --remove-gm-trips N` +(无 bishengir 方言时退回第 1′ 步的 JSON 代理)。 + +完整闭环步骤: + +1. **重写 HIR(生产路径,C++)**:用 `HivmOpsEditor` 按 §3–§7 改写 `hivm.*` op,导出优化后 `.npuir.mlir`(见上图工作流)。 +2. **导出投影**:`tritonsim-hivm --npuir-file k.opt.npuir.mlir --des-graph-file opt_des.json`。 +3. **建模对比(Python)**:`hivm_extractor.load_hivm_desgraph` → `compute_bounds`/`combine`, + 比较优化前后的 `T_bound`、`binding_component`、5 轴 `Attribution`。 +4. **counterfactual 验证**(根据是否具备 bishengir 环境,选择以下方式之一): + +- **正式验证(有 bishengir)** + 直接使用 `perfbound/validate/counterfactual.py::run_counterfactual`,对比优化前后 `.npuir.mlir` 导出的 DES‑graph,验证 `T_bound` 的下降(B 类)或 gap 收敛(A 类)。 + +- **快速代理(无 bishengir)** + 用 `hivm_edits.py` 在 DES‑graph JSON 上执行等价编辑(例如合并传输、提高 repeat),然后通过 `verify_edit_via_extract` 检查 op 数、总 `repeat`、总 `bytes` 是否按预期变化,并重算 `T_bound` 以评估效果。 + +无论采用哪种方式,如有编译器环境,还可进行**编译实测**,最终校验 `T_bound ≤ T_measured` 的守恒性。 + + + +> 注意 JSON 代理(`hivm_edits.py`)与真实 HIR 改写(`HivmOpsEditor`)是**同一变换的两种落地**: +> 前者改 DES-graph 投影用于快速 counterfactual,后者改真实 HIR 用于产出可编译的优化后 `.npuir.mlir`。 +> 两者应保持语义一致(例如 `insert_pingpong`(JSON, 复制 op 近似) ↔ `insertDoubleBuffering`(HIR, 真实双 buffer))。 + +**判读规则**(区分两种优化的成败标准): +- **(A) 缩小 gap 类**(§3 全部、§4②③⑤、§5②③、§6②③、§7 全部):`T_bound` **应保持不变**, + 实测/DES 关键路径下降、对应 `gapN_frac` 下降即成功。若 `T_bound` 变了,说明改到了流量/计算, + 归类错误。 +- **(B) 降低 bound 类**(§4①④、§5①、§6①④⑤):`T_bound` **本身应下降**,且仍满足 + `T_bound ≤ T_measured` 守恒(§spec 4.0)。 + +--- + +## 9. 落地原语现状(代码更新后已重写) + +代码更新后,执行器分两层:**Python `hivm_edits.py`(DES-graph JSON 代理,无需 bishengir)** +与 **C++ `HivmOpsEditor`(真实 HIR,需 `TRITONSIM_HAS_BISHENGIR_HIVM`)**。后者已内置大量原语, +原「⬜ 待建」多数变为「✅ 有底层原语 / ⚙ 待组合成 gap 专用 pass」。 + +### 9.1 Python 侧(DES-graph JSON 代理,counterfactual 用) + +| 原语 | 覆盖手段 | 缺口 | +|------|----------|------| +| `raise_repeat` ✅ | §6②(Gap4 repeat/mask) | 仅 JSON;不产出 HIR | +| `insert_pingpong` ✅ | §3②⑤/§4②/§7①(近似) | 复制 op 近似,非真实双 buffer | +| `merge_transfers` ✅ | §5② / §4①(部分) | 仅相邻同 space MTE_GM | + +### 9.2 C++ 侧 `HivmOpsEditor`(真实 HIR,产出优化后 `.npuir.mlir`) + +| 手段 | `HivmOpsEditor` 原语 | 现状 | +|------|---------------------|------| +| §3① barrier→p2p | `addSetFlagWaitFlagBefore/After` + `deleteAllOpsOfKind()` / `deleteSyncOpsForOp` | ✅ 底层原语齐;⚙ 待组合 + 合法性判定 | +| §3③ reorder 减 stall | (无 `moveOp`;可 delete+create 间接) | ⚙ 缺直接 move 原语 | +| §3④ 全局去屏障 | `deleteAllOpsWithName("pipe_barrier")` / `deleteSyncOpsForOp` | ✅ 原语齐;⚙ 待冗余判定 | +| §3②⑤/§4②/§7① 双缓冲 | **`insertDoubleBuffering(src, ub0, ub1, setPipe, waitPipe, eventId)`** | ✅ **直接便捷方法**(真实双 buffer,非近似) | +| §4① 减搬运/复用 | **`removeRedundantLoadStorePair(n)`** / `deleteRedundantGMTrips(n)` | ✅ 直接 | +| §4③/§6③ prefetch 到 L1 | `addND2NZBefore/After` + `changeMemorySpace("gm","l1")` | ✅ 原语齐;⚙ 待发射点上移逻辑 | +| §5①/§6①④ 增大 tile/K | `changeShape(old,new)`;K:`addMmadL1*`(realM/realK/realN) | ✅ 原语齐;⚙ 须接 buffer 容量检查 | +| §5③/§6② 融合 vector | **`fuseConsecutiveComputeOps()`** | ✅ 直接 | +| §7② Cube-Vector split | `addSyncBlockSetBefore/After`、`addSyncBlockWaitBefore/After`(跨核 `TCoreType`) | ✅ 跨核同步原语齐;⚙ 待分核逻辑 | +| 通用改属性 | `changePipeAttr`/`changeEventAttr`/`setSetFlagPipe`/`setEventId`/`replaceOpWith` | ✅ | + +> 图例:✅=原语已存在;⚙=需把原语组合成「gap 专用、带合法性判定」的高层 pass(非从零造原语)。 + +**建议优先级**(重排): +1. **直接可用、零新原语**:`insertDoubleBuffering`(§3②⑤/§4②/§7①)、`fuseConsecutiveComputeOps`(§5③/§6②)、 + `removeRedundantLoadStorePair`(§4①)——先把这三条接进「诊断→改写→重算 `T_bound`」闭环跑通端到端。 +2. **原语齐、只差组合**:`barrier_to_p2p`(§3①④)——用 `addSetFlagWaitFlag*` + `deleteSyncOpsForOp` + 组合,补 buffer 依赖证明做合法性。 +3. **需联动其它模型**:`enlarge_tile`(§5①/§6①④,`changeShape`/`addMmadL1` + `UnifiedTilingCostModel` + buffer check)、`cube_vector_split`(§7②)。 +4. **仍缺底层原语**:reorder(§3③)——`HivmOpsEditor` 暂无 `moveOp`,需新增或用 delete+create 间接实现。 + +--- + +## 附:手段 → 轴 → 原语 速查 + +图例:原语列给「Python(JSON) / C++(HivmOpsEditor, 真实 HIR)」;✅=可用,⚙=原语齐待组合,⬜=缺。 + +| § | 手段 | 轴 | 性质 | Python(JSON) | C++ HivmOpsEditor(HIR) | +|---|------|----|----|----|----| +| 3① | barrier→p2p | Gap3 | A | ⬜ | `addSetFlagWaitFlag*`+`deleteSyncOpsForOp` ⚙ | +| 3② | multibuf 降屏障频率 | Gap3 | A | `insert_pingpong` ✅(近似) | `insertDoubleBuffering` ✅ | +| 3③ | reorder 减 stall | Gap3 | A | ⬜ | 无 moveOp ⬜ | +| 3④ | 全局去屏障 | Gap3 | A | ⬜ | `deleteAllOpsWithName`/`deleteSyncOpsForOp` ⚙ | +| 3⑤ | 多 buf 解耦 | Gap3 | A | `insert_pingpong` ✅(近似) | `insertDoubleBuffering` ✅ | +| 4① | 减搬运/复用 | MTE floor | B | `merge_transfers` ✅(部分) | `removeRedundantLoadStorePair`/`deleteRedundantGMTrips` ✅ | +| 4② | 传输计算重叠 | Gap3 | A | `insert_pingpong` ✅ | `insertDoubleBuffering` ✅ | +| 4③ | CubeMTE2 prefetch | Gap3 | A | ⬜ | `addND2NZ*`+`changeMemorySpace` ⚙ | +| 4④ | 减总量/提复用 | floor | B | ⬜ | `changeShape` ⚙ | +| 4⑤ | software pipelining | Gap3 | A | `insert_pingpong` ✅(近似) | `insertDoubleBuffering` ✅ | +| 5① | 增大 tile 摊 startup | E轴 | B/A | ⬜ | `changeShape` ⚙(+buffer check) | +| 5② | 融合相邻传输 | Gap2 | A | `merge_transfers` ✅ | `removeRedundantLoadStorePair` ✅ | +| 5③ | 融合相邻 vector | Gap4 | A | ⬜ | `fuseConsecutiveComputeOps` ✅ | +| 6① | 增大 K | Cube floor | B | ⬜ | `addMmadL1*`(realK) ⚙ | +| 6② | 融合 vector | Gap4 | A | `raise_repeat` ✅ | `fuseConsecutiveComputeOps` ✅ | +| 6③ | prefetch 重叠 | Gap3 | A | ⬜ | `addND2NZ*`+`changeMemorySpace` ⚙ | +| 6④ | 增大 K/M/N | floor | B | ⬜ | `changeShape`/`addMmadL1*` ⚙ | +| 6⑤ | op 融合 | floor+serial | B/A | ⬜ | `fuseConsecutiveComputeOps`+`removeRedundantLoadStorePair` ⚙ | +| 7① | 多 buf 重叠 | Gap3 | A | `insert_pingpong` ✅ | `insertDoubleBuffering` ✅ | +| 7② | Cube-Vector split | Gap3+grid | A | ⬜ | `addSyncBlockSet/Wait*`(跨核) ⚙ | +| 7③ | 增 pipeline depth | Gap3 | A | ⬜ | `insertDoubleBuffering`(多次/扩参) ⚙ |