Fix #35: MergeBatch L1绑定情形 DMA 命令数多计 b0 倍修复 + 分界泛化口径

- evaluate: 每核命令数 = ceil(b_core/b0) * ceil(K/k_l1^m) (K截断退化为 b_core/b0,
  数值不变; L1绑定消除 b0 倍多计 —— v1.1 §4.4 恒劣恒等式的 n_K 是未合并粒度,
  误代入合并后段数会多计 b0 倍, 可把仲裁方向翻错)
- beats_iterbatch: 泛化为实际命令数比较 (cmds_iter=b_core*ceil(K/k_l1_iter) vs
  cmds_mb=ceil(b_core/b0)*ceil(K/k_l1^m), 节省>T_cmd vs drain 惩罚); K截断时严格
  退化为文档闭式 b_core > b0*(T_comp+T_write)/T_cmd; 截断判定改用合并口径
  plan.k_l1>=K (未合并截断不代表合并后截断); 覆盖 dValue 512B cap 第三情形;
  T_cmd<=0 策略路径改为 cmds_mb<cmds_iter 判 MergeBatch 优先
- router: 仲裁文案 [裁决] 位打印最终胜者 (修复分界/时延不一致时的自相矛盾表述)
- 用户 case 家族 B=128,M=1~16,N=128,K=512 修复后: m=1/2/4 -> MergeBatch,
  m=8/16 -> IterBatch (修复前全判 IterBatch; 交叉点 m≈4~8, 物理合理)
- 测试: TestIssue35 回归 5 例 (命令数公式/K截断不变/口径一致/路由家族/裁决文案);
  test_beats_iterbatch_policy 的 (128,64,64,512) 期望 True->False (第三情形:
  合并侧 dValue cap 截断, 命令数 4=4 打平, 恒劣 —— 原期望基于误分类)
- docs/01_MergeBatch分支.md: 分界小节补第三情形行 + 命令数口径警示 + 泛化净收益式
- 验证: 68/68 unittest; examples 重生成可复现 0 diff (仅仲裁文案 + 16.0->16 格式,
  plans.csv 不变); 压力 10000 例 (seed7/6000+seed2024/4000): 0 崩溃/0 NaN/0 违规/
  0 不可行/0 GM<V_in, 七分支全覆盖
This commit is contained in:
2026-09-07 20:31:51 +08:00
parent 0cd47f93cb
commit fdd3c8883c
6 changed files with 170 additions and 60 deletions

View File

@@ -7,9 +7,10 @@
核心思想: 合并 b0 个 batch 的 A'[b0*M,K] @ B'[K,b0*N] 为单次 DMA 搬入, 核心思想: 合并 b0 个 batch 的 A'[b0*M,K] @ B'[K,b0*N] 为单次 DMA 搬入,
减少 GM->L1 搬移命令数 (省 b0 倍 T_cmd); 交叉项被算出但丢弃 (冗余比例 (b0-1)/b0), 减少 GM->L1 搬移命令数 (省 b0 倍 T_cmd); 交叉项被算出但丢弃 (冗余比例 (b0-1)/b0),
进入条件 5 保证 case 为访存 Bound, 冗余算力被搬移时延掩盖. 进入条件 5 保证 case 为访存 Bound, 冗余算力被搬移时延掩盖.
T_cmd=0 时 (无命令固定时延/未标定) 命令时延收益不可量化, 但合并仍省 b0 倍 T_cmd=0 时 (无命令固定时延/未标定) 命令时延收益不可量化, 但合并仍可减少
搬移命令/主机指令数 (指令发射/调度/同步收益未建模) —— beats_iterbatch 按既定 搬移命令/主机指令数 (指令发射/调度/同步收益未建模) —— beats_iterbatch 按既定
策略裁决: K截断即优先 MergeBatch (模型内代价仅 drain 惩罚), L1 绑定恒劣. 策略裁决: 合并后实际每核命令数更少即优先 MergeBatch (模型内代价仅 drain 惩罚),
命令数打平恒劣 (issue#35 泛化口径, 覆盖 dValue 512B cap 截断等第三情形).
""" """
from __future__ import annotations from __future__ import annotations
@@ -194,7 +195,7 @@ class MergeBatchBranch(Branch):
out_l2 = output_to_l2(case, s, 0.0) out_l2 = output_to_l2(case, s, 0.0)
w_fix = s.bw_l2_pc if out_l2 else s.bw_pc w_fix = s.bw_l2_pc if out_l2 else s.bw_pc
k_truncated = k_l1 >= k k_truncated = k_l1 >= k # 保留语义标记 (plan.note/调试用)
# 每 K 分块计算时延 (未合并基准, v1.1 §4.1 符号) / 单 batch 输出写回 (R4) # 每 K 分块计算时延 (未合并基准, v1.1 §4.1 符号) / 单 batch 输出写回 (R4)
t_comp_chunk = 2.0 * m * n * k_l1 / qc t_comp_chunk = 2.0 * m * n * k_l1 / qc
t_write = m * n * out_b / w_fix t_write = m * n * out_b / w_fix
@@ -202,14 +203,14 @@ class MergeBatchBranch(Branch):
# 搬移 (issue#31): 合并组/切 K 各 (组, K段) 数据互不重叠, 每个输入字节恰好 # 搬移 (issue#31): 合并组/切 K 各 (组, K段) 数据互不重叠, 每个输入字节恰好
# 从 GM 读一次 (K截断与 L1 绑定均如此; 切 K 末段按实际剩余计, 不再整段上取) # 从 GM 读一次 (K截断与 L1 绑定均如此; 切 K 末段按实际剩余计, 不再整段上取)
# -> GM 数据量 = V_in, 数据时延 = V_in/芯片带宽 (全核并发); # -> GM 数据量 = V_in, 数据时延 = V_in/芯片带宽 (全核并发);
# 搬移命令数只决定 T_cmd (与 IterBatch 的同/少 b0 倍关系不变): # 搬移命令数只决定 T_cmd (issue#35 修正: 真实命令数 = 合并组数 x 每组 K 段数,
# K截断: 每核 b_core/b0 次合并搬入 (每次 b0 个 batch 全 K) # 不得把"命令数与 IterBatch 相同 = b_core*n_K"(v1.1 §4.4, n_K 为未合并粒度)
# L1绑定: k_L1^m = k_L1/b0, n_K^m = b0*n_K, 命令数与 IterBatch 相同 # 误代入合并后段数 —— 那样会多计 b0 倍):
if k_truncated: # K截断: n_K^m = 1 -> cmds = ceil(b_core/b0) (比 IterBatch 省 b0 倍)
dma_cmds = b_core / b0 # L1绑定: k_L1^m = k_L1/b0 理想情形退化为 b_core*n_K, 与 IterBatch 相同;
else: # dValue 512B cap 截断等情形按实际 ceil(K/k_l1^m) 计
n_k = -(-k // k_l1) n_k = -(-k // k_l1)
dma_cmds = b_core * n_k dma_cmds = -(-b_core // b0) * n_k
t_dma_cmd = dma_cmds * s.t_cmd t_dma_cmd = dma_cmds * s.t_cmd
t_mte2_data = case.input_bytes / s.bw_gm t_mte2_data = case.input_bytes / s.bw_gm
t_mte2 = t_mte2_data + t_dma_cmd t_mte2 = t_mte2_data + t_dma_cmd
@@ -243,54 +244,83 @@ class MergeBatchBranch(Branch):
def beats_iterbatch(self, case: BmmCase) -> tuple: def beats_iterbatch(self, case: BmmCase) -> tuple:
"""返回 (MergeBatch是否更优, 说明). """返回 (MergeBatch是否更优, 说明).
MergeBatch 最优 ⟺ K截断 (k_L1=K) 且 b_core > b0*(T_comp+T_write)/T_cmd v1.1 §4.5 统一分界的泛化口径 (issue#35): 直接比较两分支**实际每核 DMA
L1 绑定情形 MergeBatch 恒劣于 IterBatch (搬移次数相同, 只放大 drain). 命令数**与 drain 惩罚 ——
cmds_iter = b_core * ⌈K/k_l1_iter⌉ (IterBatch 逐 batch 逐 K 段一条)
cmds_mb = ⌈b_core/b0⌉ * ⌈K/k_l1^m⌉ (合并组数 x 每组 K 段数)
搬移节省 = (cmds_iter - cmds_mb) * T_cmd
drain 惩罚 = (b0-1) * (T_comp + T_write) (T_comp 按未合并基线分块)
MergeBatch 最优 ⟺ 搬移节省 > drain 惩罚.
T_cmd=0 (无命令时延/未标定) 时阈值趋于 +inf, 但 MergeBatch 还有**未量化的 与 v1.1 §4.5 闭式的等价性:
结构性收益**: 大 B 小 MN 时搬移命令数/主机指令数省 b0 倍 (每条命令的指令 - K 截断 (k_l1^m = K): cmds_mb = b_core/b0, 退化为文档闭式
发射/调度/同步开销未建模). 因此 T_cmd<=0 采用既定策略: K截断即可胜 b_core > b0*(T_comp+T_write)/T_cmd;
(模型内代价仅为 drain 惩罚, 访存 Bound case 下小且方向已知); L1 绑定仍恒劣. - L1 绑定理想情形 (k_l1^m = k_l1^iter/b0): 命令数相同, 节省=0 -> 恒劣;
- dValue 512B 推荐值截断等第三情形 (文档二分未覆盖): 按实际命令数比较.
截断判定用**合并后** plan.k_l1 >= K (与 make_plan/evaluate 同源,
issue#35): 未合并 k_l1 截断不代表合并后仍截断 (合并使 L1 占用放大 b0 倍,
且受 dValue 512B 推荐值截断), v1.1 line 219 的字面定义 (未合并口径) 与
line 161 的合并公式矛盾时以后者为准.
T_cmd<=0 (无命令时延/未标定) 时阈值不可量化: 按既定策略, 合并后每核命令数
更少 (cmds_mb < cmds_iter, 结构性指令/调度收益未建模) 即判 MergeBatch 优先;
命令数打平则恒劣 (合并只放大 drain).
""" """
s = self.spec s = self.spec
m, n, k = case.m, case.n, case.k m, n, k = case.m, case.n, case.k
dt = case.dtype_in_bytes
out_b = case.dtype_out_bytes out_b = case.dtype_out_bytes
b_core = case.batch_c // s.aic_num b_core = case.batch_c // s.aic_num
# IterBatch 基准的 k_L1 (未合并): L1 双缓冲单 batch # IterBatch 基线的每核命令数 (与 iter_batch.evaluate 同源: 形态 a/b 时
k_l1_iter = min(k, s.l1_bytes / (2 * (m + n) * dt)) # k_l1=K 一次一条; c/d 形态按 l1_form 判定的 k_l1 分段)
k_truncated = k_l1_iter >= k from .iter_batch import IterBatchBranch
_, k_l1_iter, _ = IterBatchBranch(s).l1_form(case)
if not k_l1_iter:
k_l1_iter = k
n_k_iter = -(-k // min(k_l1_iter, k))
cmds_iter = b_core * n_k_iter
# MergeBatch 实际每核命令数 (issue#35: 合并组数 x 每组 K 段数)
plan = self.make_plan(case) plan = self.make_plan(case)
b0 = plan.merge_b0 b0 = plan.merge_b0
# T_comp 按输入 dtype 算力 (issue#28); T_write 保持 v1.1 直写 GM 语义 n_k_mb = -(-k // min(plan.k_l1, k))
cmds_mb = -(-b_core // b0) * n_k_mb
k_truncated = plan.k_l1 >= k # 合并口径截断判定 (issue#35)
regime = f"K截断(k_l1^m={plan.k_l1}>=K)" if k_truncated else \
f"L1绑定(k_l1^m={plan.k_l1}<K={k})"
# T_comp 按输入 dtype 算力 (issue#28), 未合并基线分块 (v1.1 §4.1 符号);
# T_write 保持 v1.1 直写 GM 语义
qc = s.q_cube(case.dtype_a, case.dtype_b) qc = s.q_cube(case.dtype_a, case.dtype_b)
t_comp = 2.0 * m * n * min(k_l1_iter, k) / qc t_comp = 2.0 * m * n * min(k_l1_iter, k) / qc
t_write = m * n * out_b / s.bw_pc t_write = m * n * out_b / s.bw_pc
drain_pen = (b0 - 1) * (t_comp + t_write) drain_pen = (b0 - 1) * (t_comp + t_write)
save_cmds = cmds_iter - cmds_mb
if s.t_cmd <= 0: if s.t_cmd <= 0:
# T_cmd=0: 命令时延收益不可量化 -> 阈值 +inf; 按策略裁决 (见 docstring). # T_cmd=0: 命令时延收益不可量化 -> 按结构性命令数比较的策略裁决
# 大 B 小 MN 时合并把 b_core 条搬移/计算命令序列并为 b_core/b0 条, # (合并把搬移/计算命令序列并少, 指令发射/调度/同步收益存在但未量化);
# 指令发射/调度/同步收益存在但未量化 —— K截断时判胜, 由路由层以策略覆盖 # 命令数打平时合并只放大 drain -> 恒劣.
# 时延模型比较; L1 绑定 (搬移次数与 IterBatch 相同) 仍恒劣. if cmds_mb < cmds_iter:
if k_truncated: detail = (f"{regime}; T_cmd=0: 命令时延收益不可量化(阈值=+inf), "
detail = (f"k_L1=K(截断); T_cmd=0: 命令时延收益不可量化(阈值=+inf), " f"合并后每核命令数 {cmds_mb} < IterBatch {cmds_iter} "
f"但合并省 {b0} 倍搬移命令/指令数 (结构性收益, 未量化) -> " f"(结构性收益, 未量化) -> 策略优先 MergeBatch; "
f"策略优先 MergeBatch; 模型内代价 drain 惩罚=" f"模型内代价 drain 惩罚={drain_pen*1e6:.2f}us")
f"{drain_pen*1e6:.2f}us")
return True, detail return True, detail
detail = (f"k_L1={k_l1_iter:.0f}<K(L1绑定); T_cmd=0: 搬移命令次数与 " detail = (f"{regime}; T_cmd=0: 每核命令数 MergeBatch={cmds_mb} 不少于 "
f"IterBatch 相同, 合并只放大 drain 惩罚={drain_pen*1e6:.2f}us -> 恒劣") f"IterBatch={cmds_iter}, 合并只放大 drain 惩罚="
f"{drain_pen*1e6:.2f}us -> 恒劣")
return False, detail return False, detail
threshold = b0 * (t_comp + t_write) / s.t_cmd savings = save_cmds * s.t_cmd
win = savings > drain_pen
win = k_truncated and (b_core > threshold) detail = (f"{regime}; 每核命令数 MergeBatch={cmds_mb} vs IterBatch={cmds_iter}, "
detail = (f"k_L1={'K(截断)' if k_truncated else f'{k_l1_iter:.0f}<K(L1绑定)'}; " f"搬移节省={savings*1e6:.2f}us vs drain惩罚=(b0-1)*(T_comp+T_write)="
f"b_core={b_core} vs 阈值 b0*(T_comp+T_write)/T_cmd={threshold:.1f}; " f"{drain_pen*1e6:.2f}us -> {'MergeBatch优' if win else 'IterBatch优'}")
f"drain惩罚=(b0-1)*(T_comp+T_write)={drain_pen*1e6:.2f}us, " if k_truncated:
f"搬移节省=b_core*(1-1/b0)*T_cmd={b_core*(1-1/b0)*s.t_cmd*1e6:.2f}us") detail += (f" (闭式等价: b_core={b_core} vs 阈值 "
f"b0*(T_comp+T_write)/T_cmd={b0 * (t_comp + t_write) / s.t_cmd:.1f})")
return win, detail return win, detail
# ------------------------------------------------------------------ # ------------------------------------------------------------------

View File

@@ -110,10 +110,10 @@ class BranchRouter:
f"两分支均合法, 仲裁: " f"两分支均合法, 仲裁: "
f"[分界条件] MergeBatch最优={mb_win} ({detail}); " f"[分界条件] MergeBatch最优={mb_win} ({detail}); "
f"[时延模型] T_MergeBatch={t_mb*1e6:.2f}us vs T_IterBatch={t_ib*1e6:.2f}us -> {lat_win}更优; " f"[时延模型] T_MergeBatch={t_mb*1e6:.2f}us vs T_IterBatch={t_ib*1e6:.2f}us -> {lat_win}更优; "
f"[裁决] {win}" + ("" if win == lat_win else f" (分界条件与时延模型不一致, 以时延模型为准: {lat_win})") f"[裁决] {lat_win}" + ("" if win == lat_win else
f" (分界条件判{win}, 与时延模型不一致, 以时延模型为准)")
) )
if win != lat_win: win = lat_win # 时延模型为最终裁决
win = lat_win # 时延模型为最终裁决
elif any(capable.values()): elif any(capable.values()):
win = next(n for n, v in capable.items() if v) win = next(n for n, v in capable.items() if v)
arbitration = f"{win} 条件满足" arbitration = f"{win} 条件满足"

View File

@@ -47,25 +47,36 @@ k_L1 被 512B 截断省出的 L1 空间容纳更多 batch提升 batch 间流
$$T_{mb} = \underbrace{\frac{b_{core}}{b_0}\cdot n_K^m\cdot(T_{load}^m + T_{cmd})}_{\text{搬移(合并)}} + \underbrace{b_0(T_{comp}+T_{write})}_{\text{末合并 batch drain}}$$ $$T_{mb} = \underbrace{\frac{b_{core}}{b_0}\cdot n_K^m\cdot(T_{load}^m + T_{cmd})}_{\text{搬移(合并)}} + \underbrace{b_0(T_{comp}+T_{write})}_{\text{末合并 batch drain}}$$
两种情形 两种经典情形 (v1.1 §4.34.4) 与第三情形 (issue#35):
| 情形 | k_L1^m | n_K^m | 搬移命令数 | 结论 | | 情形 | k_L1^m | n_K^m | 每核搬移命令数 (⌈b_core/b₀⌉·n_K^m) | 结论 |
|---|---|---|---|---| |---|---|---|---|---|
| **K 截断** (k_L1=K) | K 不减半 | 1 | b_core/b₀( b | MergeBatch 可胜 | | **K 截断** (k_L1^m=K) | K | 1 | b_core/b IterBatch b | MergeBatch 可胜 |
| **L1 绑定** (k_L1<K) | k_L1/b | b₀·n_K | b_core·n_K IterBatch 相同 | **MergeBatch 恒劣** | | **L1 绑定** (k_L1^m=k_L1^iter/b₀) | k_L1^iter/b | b₀·n_K | b_core·n_K IterBatch 相同 | **MergeBatch 恒劣** |
| **dValue cap 截断** (k_L1^m=512B/dt, 文档二分未覆盖) | 512B/dt | K/k_L1^m | 按实际比较 (可与 IterBatch 打平或少) | 按泛化分界判定 |
L1 绑定情形搬移次数单次搬移量都与 IterBatch 相同只放大 drain——证明见 v1.1 §4.4 L1 绑定理想情形搬移次数单次搬移量都与 IterBatch 相同只放大 drain——证明见 v1.1 §4.4
第三情形例: IterBatch a/b 形态 (k_L1=K) 而合并侧被 512B 推荐值截断时, n_K^m=n_K,
命令数打平 (既不省 b 倍也不放大), 合并仅剩 drain 惩罚 -> 恒劣; 反之若 IterBatch 走
c/d 形态切 K 而合并侧每核命令数更少, 则按实际节省判定。
> **每核命令数口径 (issue#35)**: 真实命令数 = **合并组数 × 每组 K 段数** =
> ⌈b_core/b₀⌉·⌈K/k_L1^m⌉。注意 v1.1 §4.4 "命令数与 IterBatch 相同 = b_core·n_K" 中的
> n_K 是**未合并**粒度 (⌈K/k_L1^iter⌉); 误代入合并后段数 ⌈K/k_L1^m⌉ 会多计 b₀ 倍
> (修复前 evaluate 即此错, L1 绑定情形命令时延虚高 b₀ 倍, 可把仲裁方向翻错)。
> **GM 数据量口径 (issue#31)**: 各 (合并组, K段) 的数据互不重叠, 每个输入字节恰好从 GM > **GM 数据量口径 (issue#31)**: 各 (合并组, K段) 的数据互不重叠, 每个输入字节恰好从 GM
> 读一次 —— K 截断与 L1 绑定两种情形的**芯片 GM 读取量都 = V_in** (末段按实际剩余计, > 读一次 —— K 截断与 L1 绑定两种情形的**芯片 GM 读取量都 = V_in** (末段按实际剩余计,
> 无 padding 上取)。上式的 T_load 级联只用于刻画命令/双缓冲调度结构: 数据时延按 > 无 padding 上取)。上式的 T_load 级联只用于刻画命令/双缓冲调度结构: 数据时延按
> V_in/W_GM 计, n_K 只放大 DMA 命令项 (b_core/b₀ 或 b_core·n_K) × T_cmd。 > V_in/W_GM 计, n_K 只放大 DMA 命令项 b_core/b₀·n_K^m × T_cmd (issue#35 口径)
## 5. MergeBatch vs IterBatch 净收益 ## 5. MergeBatch vs IterBatch 净收益
$$\text{净收益} = \underbrace{b_{core}\Big(1-\frac{1}{b_0}\Big)T_{cmd}}_{\text{搬移命令节省}} - \underbrace{(b_0-1)(T_{comp}+T_{write})}_{\text{drain 惩罚}}$$ 泛化分界 (issue#35, 覆盖三种情形): 直接比较两分支**实际每核 DMA 命令数** ——
Bb_core 且小 MNT_comp MergeBatch 最优T_cmd 的物理成因Nd2Nz 描述符配置7 字段写 DMA 寄存器+ 地址生成 + 突发启动 + L1 同步握手 $$\text{净收益} = \underbrace{(cmds_{iter}-cmds_{mb})\,T_{cmd}}_{\text{搬移命令节省}} - \underbrace{(b_0-1)(T_{comp}+T_{write})}_{\text{drain 惩罚}},\qquad \begin{array}{l}cmds_{iter}=b_{core}\lceil K/k_{L1}^{iter}\rceil\\ cmds_{mb}=\lceil b_{core}/b_0\rceil\lceil K/k_{L1}^m\rceil\end{array}$$
K 截断时严格退化为 v1.1 §4.5 闭式 b_core > b₀(T_comp+T_write)/T_cmdL1 绑定理想情形命令数打平、净收益恒负。大 Bb_core 大)且小 MNT_comp 小)时 MergeBatch 最优。T_cmd 的物理成因Nd2Nz 描述符配置7 字段写 DMA 寄存器)+ 地址生成 + 突发启动 + L1 同步握手。
## 6. 与源码的差异v1.1 §5.1 ## 6. 与源码的差异v1.1 §5.1

View File

@@ -2,7 +2,7 @@
to_matmul_demo,1,1,2048,2048,2048,bf16,bf16,bf16,False,False,False,True,0,to_matmul_demo,转Matmul,Ascend950PR,batch_mat_mul_v3,32,1,0,0,1,"折叠为 Matmul [2048,2048]x[2048,2048], 复用 Matmul 切分体系",0,1,0,0,2048,0,1,,0,0,0,,,0,0,转Matmul后由 Matmul 体系决定,1,1,1,0,0,0,0,True,2,"BatchB=1免费折叠: 左矩阵 [1,2048,2048] 视图折叠为 [2048,2048], 零重排零 split",16777216,0.0,1.048576e-05,0.0,1.048576e-05,0.0,0.0,17179869184.0,3.534952506995885e-05,8388608,1.6131938461538462e-06,0.0,3.534952506995885e-05,0.0,3.534952506995885e-05,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除" to_matmul_demo,1,1,2048,2048,2048,bf16,bf16,bf16,False,False,False,True,0,to_matmul_demo,转Matmul,Ascend950PR,batch_mat_mul_v3,32,1,0,0,1,"折叠为 Matmul [2048,2048]x[2048,2048], 复用 Matmul 切分体系",0,1,0,0,2048,0,1,,0,0,0,,,0,0,转Matmul后由 Matmul 体系决定,1,1,1,0,0,0,0,True,2,"BatchB=1免费折叠: 左矩阵 [1,2048,2048] 视图折叠为 [2048,2048], 零重排零 split",16777216,0.0,1.048576e-05,0.0,1.048576e-05,0.0,0.0,17179869184.0,3.534952506995885e-05,8388608,1.6131938461538462e-06,0.0,3.534952506995885e-05,0.0,3.534952506995885e-05,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
special_k0_demo,128,128,256,256,0,bf16,bf16,bf16,False,False,False,True,0,special_k0_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,0,0,1,UB驻留(AIV),0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=0纯写值: 无任何计算, C=bias 或 0, 纯 AIV 写值; 按行均分到 AIV 核",0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),"瓶颈在 Fixpipe 写出: 检查输出 dtype (fp16/fp8 可减半写出量), 或评估输出驻留 L2 异步回写策略" special_k0_demo,128,128,256,256,0,bf16,bf16,bf16,False,False,False,True,0,special_k0_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,0,0,1,UB驻留(AIV),0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=0纯写值: 无任何计算, C=bias 或 0, 纯 AIV 写值; 按行均分到 AIV 核",0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),"瓶颈在 Fixpipe 写出: 检查输出 dtype (fp16/fp8 可减半写出量), 或评估输出驻留 L2 异步回写策略"
special_k1_demo,128,128,256,256,1,bf16,bf16,bf16,False,False,False,True,0,special_k1_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,1,0,1,UB驻留(AIV) UB乒乓,0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=1逐元素乘: 退化为 C=A⊙B 无累加深度, Cube 16x16x16 粒度浪费 15/16; 走 AIV 通路 GM->UB->Mul->GM, UB乒乓 (B>=2*AIV 双batch乒乓流水)",131072,0.0,8.192e-08,0.0,8.192e-08,0.0,0.0,8388608.0,3.103030303030303e-07,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),"瓶颈在 Fixpipe 写出: 检查输出 dtype (fp16/fp8 可减半写出量), 或评估输出驻留 L2 异步回写策略" special_k1_demo,128,128,256,256,1,bf16,bf16,bf16,False,False,False,True,0,special_k1_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,1,0,1,UB驻留(AIV) UB乒乓,0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=1逐元素乘: 退化为 C=A⊙B 无累加深度, Cube 16x16x16 粒度浪费 15/16; 走 AIV 通路 GM->UB->Mul->GM, UB乒乓 (B>=2*AIV 双batch乒乓流水)",131072,0.0,8.192e-08,0.0,8.192e-08,0.0,0.0,8388608.0,3.103030303030303e-07,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),"瓶颈在 Fixpipe 写出: 检查输出 dtype (fp16/fp8 可减半写出量), 或评估输出驻留 L2 异步回写策略"
merge_demo_k_trunc,2048,2048,32,32,256,bf16,bf16,bf16,False,False,False,True,0,merge_demo_k_trunc,MergeBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B均分(核间零重复读零依赖),64,4,128,128,256,256,8,合并驻留,128,128,128,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"b0=4 (L0C上限5.7/算存比上限19.0/b_core=64); K截断; 合并后单次DMA搬入 A'[128,256]+B'[256,128]; 输出落点: L2驻留 (整case V_in+V_out=64.0MB vs L2=128MB)",67108864,0.0,4.194304e-05,0.0,4.2743039999999997e-05,16.0,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,4194304,8.065969230769231e-07,0.0,4.2743039999999997e-05,1.8849638999683443e-07,4.293153638999683e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争" merge_demo_k_trunc,2048,2048,32,32,256,bf16,bf16,bf16,False,False,False,True,0,merge_demo_k_trunc,MergeBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B均分(核间零重复读零依赖),64,4,128,128,256,256,8,合并驻留,128,128,128,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"b0=4 (L0C上限5.7/算存比上限19.0/b_core=64); K截断; 合并后单次DMA搬入 A'[128,256]+B'[256,128]; 输出落点: L2驻留 (整case V_in+V_out=64.0MB vs L2=128MB)",67108864,0.0,4.194304e-05,0.0,4.2743039999999997e-05,16,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,4194304,8.065969230769231e-07,0.0,4.2743039999999997e-05,1.8849638999683443e-07,4.293153638999683e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
merge_iter_arbitrate,128,128,64,64,512,bf16,bf16,bf16,False,False,False,True,0,merge_iter_arbitrate,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,512,512,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=256KB <= L1; 输出落点: L2驻留,16777216,0.0,1.048576e-05,0.0,1.0685759999999999e-05,4,2.0000000000000002e-07,536870912.0,1.104672658436214e-06,1048576,2.0164923076923077e-07,0.0,1.0685759999999999e-05,3.265804723013612e-07,1.101234047230136e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争" merge_iter_arbitrate,128,128,64,64,512,bf16,bf16,bf16,False,False,False,True,0,merge_iter_arbitrate,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,512,512,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=256KB <= L1; 输出落点: L2驻留,16777216,0.0,1.048576e-05,0.0,1.0685759999999999e-05,4,2.0000000000000002e-07,536870912.0,1.104672658436214e-06,1048576,2.0164923076923077e-07,0.0,1.0685759999999999e-05,3.265804723013612e-07,1.101234047230136e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
iter_demo_form_b,128,128,64,64,256,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_b,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,256,256,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=128KB <= L1; 输出落点: L2驻留,8388608,0.0,5.24288e-06,0.0,5.4428799999999995e-06,4,2.0000000000000002e-07,268435456.0,5.52336329218107e-07,1048576,2.0164923076923077e-07,0.0,5.4428799999999995e-06,1.8849638999683443e-07,5.631376389996834e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争" iter_demo_form_b,128,128,64,64,256,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_b,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,256,256,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=128KB <= L1; 输出落点: L2驻留,8388608,0.0,5.24288e-06,0.0,5.4428799999999995e-06,4,2.0000000000000002e-07,268435456.0,5.52336329218107e-07,1048576,2.0164923076923077e-07,0.0,5.4428799999999995e-06,1.8849638999683443e-07,5.631376389996834e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
iter_demo_form_d,64,64,64,64,8192,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_d,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,64,64,8192,1024,1,d_两侧都切K,64,64,256,allocate(GM->L1随路驻留L2),"direct_gm(整case超L2: 输入优先驻留L2, 输出直写GM不占L2)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: 直写GM",134217728,0.0,8.388608e-05,0.0,8.468608e-05,16,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,524288,3.2768e-07,0.0,8.501376e-05,7.16176329218107e-07,8.572993632921812e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争" iter_demo_form_d,64,64,64,64,8192,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_d,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,64,64,8192,1024,1,d_两侧都切K,64,64,256,allocate(GM->L1随路驻留L2),"direct_gm(整case超L2: 输入优先驻留L2, 输出直写GM不占L2)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: 直写GM",134217728,0.0,8.388608e-05,0.0,8.468608e-05,16,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,524288,3.2768e-07,0.0,8.501376e-05,7.16176329218107e-07,8.572993632921812e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
1 case_id batch_a batch_b m n k dtype_a dtype_b dtype_c trans_a trans_b has_bias out_nd deterministic_level plan_case_id plan_branch plan_npu plan_op plan_used_core_num plan_split_b plan_m_cnt plan_n_cnt plan_grid_k plan_core_map plan_b_core plan_merge_b0 plan_single_core_m plan_single_core_n plan_single_core_k plan_k_l1 plan_b_l1 plan_l1_form plan_base_m plan_base_n plan_base_k plan_l2_policy_in plan_l2_policy_out plan_swizzle_w plan_workspace_bytes plan_tail_strategy plan_tail_m_cnt plan_tail_n_cnt plan_tail_k_cnt plan_tail_m_main plan_tail_n_main plan_tail_block_cnt plan_tail_wave_num plan_fixpipe_unitflag plan_out_dtype_bytes plan_note gm_read_bytes l2_read_bytes t_mte2_gm t_mte2_l2 t_mte2 dma_cmd_count t_dma_cmd cube_flops t_mmad fixpipe_bytes t_fixpipe t_reduce t_steady t_drain t_total bottleneck feasible violations bound_type advice
2 to_matmul_demo 1 1 2048 2048 2048 bf16 bf16 bf16 False False False True 0 to_matmul_demo 转Matmul Ascend950PR batch_mat_mul_v3 32 1 0 0 1 折叠为 Matmul [2048,2048]x[2048,2048], 复用 Matmul 切分体系 0 1 0 0 2048 0 1 0 0 0 0 0 转Matmul后由 Matmul 体系决定 1 1 1 0 0 0 0 True 2 BatchB=1免费折叠: 左矩阵 [1,2048,2048] 视图折叠为 [2048,2048], 零重排零 split 16777216 0.0 1.048576e-05 0.0 1.048576e-05 0.0 0.0 17179869184.0 3.534952506995885e-05 8388608 1.6131938461538462e-06 0.0 3.534952506995885e-05 0.0 3.534952506995885e-05 MMAD True 计算Bound 瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除
3 special_k0_demo 128 128 256 256 0 bf16 bf16 bf16 False False False True 0 special_k0_demo 特殊分支 Ascend950PR batch_mat_mul_v3 64 1 1 1 1 AIV 核间按行均分 (无 Cube tile 概念) 0 1 0 0 0 0 1 UB驻留(AIV) 0 0 0 allocate direct_gm 0 0 不涉及(AIV逐元素) 1 1 1 0 0 0 0 False 2 K=0纯写值: 无任何计算, C=bias 或 0, 纯 AIV 写值; 按行均分到 AIV 核 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 16777216 3.2263876923076923e-06 0.0 3.2263876923076923e-06 0.0 3.2263876923076923e-06 FIXPIPE True 写出Bound(L2写口) 瓶颈在 Fixpipe 写出: 检查输出 dtype (fp16/fp8 可减半写出量), 或评估输出驻留 L2 异步回写策略
4 special_k1_demo 128 128 256 256 1 bf16 bf16 bf16 False False False True 0 special_k1_demo 特殊分支 Ascend950PR batch_mat_mul_v3 64 1 1 1 1 AIV 核间按行均分 (无 Cube tile 概念) 0 1 0 0 1 0 1 UB驻留(AIV) UB乒乓 0 0 0 allocate direct_gm 0 0 不涉及(AIV逐元素) 1 1 1 0 0 0 0 False 2 K=1逐元素乘: 退化为 C=A⊙B 无累加深度, Cube 16x16x16 粒度浪费 15/16; 走 AIV 通路 GM->UB->Mul->GM, UB乒乓 (B>=2*AIV 双batch乒乓流水) 131072 0.0 8.192e-08 0.0 8.192e-08 0.0 0.0 8388608.0 3.103030303030303e-07 16777216 3.2263876923076923e-06 0.0 3.2263876923076923e-06 0.0 3.2263876923076923e-06 FIXPIPE True 写出Bound(L2写口) 瓶颈在 Fixpipe 写出: 检查输出 dtype (fp16/fp8 可减半写出量), 或评估输出驻留 L2 异步回写策略
5 merge_demo_k_trunc 2048 2048 32 32 256 bf16 bf16 bf16 False False False True 0 merge_demo_k_trunc MergeBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B均分(核间零重复读零依赖) 64 4 128 128 256 256 8 合并驻留 128 128 128 allocate(GM->L1随路驻留L2) resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 b0=4 (L0C上限5.7/算存比上限19.0/b_core=64); K截断; 合并后单次DMA搬入 A'[128,256]+B'[256,128]; 输出落点: L2驻留 (整case V_in+V_out=64.0MB vs L2=128MB) 67108864 0.0 4.194304e-05 0.0 4.2743039999999997e-05 16.0 16 8.000000000000001e-07 4294967296.0 8.837381267489712e-06 4194304 8.065969230769231e-07 0.0 4.2743039999999997e-05 1.8849638999683443e-07 4.293153638999683e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) 瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争
6 merge_iter_arbitrate 128 128 64 64 512 bf16 bf16 bf16 False False False True 0 merge_iter_arbitrate IterBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B轮转分配(核间零重复读零依赖) 4 1 64 64 512 512 2 b_双batch乒乓 64 64 256 allocate(GM->L1随路驻留L2) resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 双batch乒乓: 2*(MK+KN)*dtype=256KB <= L1; 输出落点: L2驻留 16777216 0.0 1.048576e-05 0.0 1.0685759999999999e-05 4 2.0000000000000002e-07 536870912.0 1.104672658436214e-06 1048576 2.0164923076923077e-07 0.0 1.0685759999999999e-05 3.265804723013612e-07 1.101234047230136e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) 瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争
7 iter_demo_form_b 128 128 64 64 256 bf16 bf16 bf16 False False False True 0 iter_demo_form_b IterBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B轮转分配(核间零重复读零依赖) 4 1 64 64 256 256 2 b_双batch乒乓 64 64 256 allocate(GM->L1随路驻留L2) resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 双batch乒乓: 2*(MK+KN)*dtype=128KB <= L1; 输出落点: L2驻留 8388608 0.0 5.24288e-06 0.0 5.4428799999999995e-06 4 2.0000000000000002e-07 268435456.0 5.52336329218107e-07 1048576 2.0164923076923077e-07 0.0 5.4428799999999995e-06 1.8849638999683443e-07 5.631376389996834e-06 MTE2 True 访存Bound(GM读写共享+L2重复读) 瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争
8 iter_demo_form_d 64 64 64 64 8192 bf16 bf16 bf16 False False False True 0 iter_demo_form_d IterBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B轮转分配(核间零重复读零依赖) 2 1 64 64 8192 1024 1 d_两侧都切K 64 64 256 allocate(GM->L1随路驻留L2) direct_gm(整case超L2: 输入优先驻留L2, 输出直写GM不占L2) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: 直写GM 134217728 0.0 8.388608e-05 0.0 8.468608e-05 16 8.000000000000001e-07 4294967296.0 8.837381267489712e-06 524288 3.2768e-07 0.0 8.501376e-05 7.16176329218107e-07 8.572993632921812e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) 瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争

View File

@@ -2,8 +2,8 @@
to_matmul_demo,1,1,2048,2048,2048,bf16,bf16,bf16,False,False,False,True,0,to_matmul_demo,转Matmul,Ascend950PR,batch_mat_mul_v3,32,1,0,0,1,"折叠为 Matmul [2048,2048]x[2048,2048], 复用 Matmul 切分体系",0,1,0,0,2048,0,1,,0,0,0,,,0,0,转Matmul后由 Matmul 体系决定,1,1,1,0,0,0,0,True,2,"BatchB=1免费折叠: 左矩阵 [1,2048,2048] 视图折叠为 [2048,2048], 零重排零 split",16777216,0.0,1.048576e-05,0.0,1.048576e-05,0.0,0.0,17179869184.0,3.534952506995885e-05,8388608,1.6131938461538462e-06,0.0,3.534952506995885e-05,0.0,3.534952506995885e-05,MMAD,True,,计算Bound,"BatchA=1或BatchB=1, 折叠转普通Matmul" to_matmul_demo,1,1,2048,2048,2048,bf16,bf16,bf16,False,False,False,True,0,to_matmul_demo,转Matmul,Ascend950PR,batch_mat_mul_v3,32,1,0,0,1,"折叠为 Matmul [2048,2048]x[2048,2048], 复用 Matmul 切分体系",0,1,0,0,2048,0,1,,0,0,0,,,0,0,转Matmul后由 Matmul 体系决定,1,1,1,0,0,0,0,True,2,"BatchB=1免费折叠: 左矩阵 [1,2048,2048] 视图折叠为 [2048,2048], 零重排零 split",16777216,0.0,1.048576e-05,0.0,1.048576e-05,0.0,0.0,17179869184.0,3.534952506995885e-05,8388608,1.6131938461538462e-06,0.0,3.534952506995885e-05,0.0,3.534952506995885e-05,MMAD,True,,计算Bound,"BatchA=1或BatchB=1, 折叠转普通Matmul"
special_k0_demo,128,128,256,256,0,bf16,bf16,bf16,False,False,False,True,0,special_k0_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,0,0,1,UB驻留(AIV),0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=0纯写值: 无任何计算, C=bias 或 0, 纯 AIV 写值; 按行均分到 AIV 核",0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),K=0纯写值 special_k0_demo,128,128,256,256,0,bf16,bf16,bf16,False,False,False,True,0,special_k0_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,0,0,1,UB驻留(AIV),0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=0纯写值: 无任何计算, C=bias 或 0, 纯 AIV 写值; 按行均分到 AIV 核",0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),K=0纯写值
special_k1_demo,128,128,256,256,1,bf16,bf16,bf16,False,False,False,True,0,special_k1_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,1,0,1,UB驻留(AIV) UB乒乓,0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=1逐元素乘: 退化为 C=A⊙B 无累加深度, Cube 16x16x16 粒度浪费 15/16; 走 AIV 通路 GM->UB->Mul->GM, UB乒乓 (B>=2*AIV 双batch乒乓流水)",131072,0.0,8.192e-08,0.0,8.192e-08,0.0,0.0,8388608.0,3.103030303030303e-07,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),"K=1逐元素乘, 走AIV向量通路" special_k1_demo,128,128,256,256,1,bf16,bf16,bf16,False,False,False,True,0,special_k1_demo,特殊分支,Ascend950PR,batch_mat_mul_v3,64,1,1,1,1,AIV 核间按行均分 (无 Cube tile 概念),0,1,0,0,1,0,1,UB驻留(AIV) UB乒乓,0,0,0,allocate,direct_gm,0,0,不涉及(AIV逐元素),1,1,1,0,0,0,0,False,2,"K=1逐元素乘: 退化为 C=A⊙B 无累加深度, Cube 16x16x16 粒度浪费 15/16; 走 AIV 通路 GM->UB->Mul->GM, UB乒乓 (B>=2*AIV 双batch乒乓流水)",131072,0.0,8.192e-08,0.0,8.192e-08,0.0,0.0,8388608.0,3.103030303030303e-07,16777216,3.2263876923076923e-06,0.0,3.2263876923076923e-06,0.0,3.2263876923076923e-06,FIXPIPE,True,,写出Bound(L2写口),"K=1逐元素乘, 走AIV向量通路"
merge_demo_k_trunc,2048,2048,32,32,256,bf16,bf16,bf16,False,False,False,True,0,merge_demo_k_trunc,MergeBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B均分(核间零重复读零依赖),64,4,128,128,256,256,8,合并驻留,128,128,128,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"b0=4 (L0C上限5.7/算存比上限19.0/b_core=64); K截断; 合并后单次DMA搬入 A'[128,256]+B'[256,128]; 输出落点: L2驻留 (整case V_in+V_out=64.0MB vs L2=128MB)",67108864,0.0,4.194304e-05,0.0,4.2743039999999997e-05,16.0,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,4194304,8.065969230769231e-07,0.0,4.2743039999999997e-05,1.8849638999683443e-07,4.293153638999683e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"两分支均合法, 仲裁: [分界条件] MergeBatch最优=True (k_L1=K(截断); b_core=64 vs 阈值 b0*(T_comp+T_write)/T_cmd=6.0; drain惩罚=(b0-1)*(T_comp+T_write)=0.23us, 搬移节省=b_core*(1-1/b0)*T_cmd=2.40us); [时延模型] T_MergeBatch=42.93us vs T_IterBatch=45.19us -> MergeBatch更优; [裁决] MergeBatch" merge_demo_k_trunc,2048,2048,32,32,256,bf16,bf16,bf16,False,False,False,True,0,merge_demo_k_trunc,MergeBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B均分(核间零重复读零依赖),64,4,128,128,256,256,8,合并驻留,128,128,128,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"b0=4 (L0C上限5.7/算存比上限19.0/b_core=64); K截断; 合并后单次DMA搬入 A'[128,256]+B'[256,128]; 输出落点: L2驻留 (整case V_in+V_out=64.0MB vs L2=128MB)",67108864,0.0,4.194304e-05,0.0,4.2743039999999997e-05,16,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,4194304,8.065969230769231e-07,0.0,4.2743039999999997e-05,1.8849638999683443e-07,4.293153638999683e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"两分支均合法, 仲裁: [分界条件] MergeBatch最优=True (K截断(k_l1^m=256>=K); 每核命令数 MergeBatch=16 vs IterBatch=64, 搬移节省=2.40us vs drain惩罚=(b0-1)*(T_comp+T_write)=0.23us -> MergeBatch优 (闭式等价: b_core=64 vs 阈值 b0*(T_comp+T_write)/T_cmd=6.0)); [时延模型] T_MergeBatch=42.93us vs T_IterBatch=45.19us -> MergeBatch更优; [裁决] MergeBatch"
merge_iter_arbitrate,128,128,64,64,512,bf16,bf16,bf16,False,False,False,True,0,merge_iter_arbitrate,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,512,512,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=256KB <= L1; 输出落点: L2驻留,16777216,0.0,1.048576e-05,0.0,1.0685759999999999e-05,4,2.0000000000000002e-07,536870912.0,1.104672658436214e-06,1048576,2.0164923076923077e-07,0.0,1.0685759999999999e-05,3.265804723013612e-07,1.101234047230136e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"两分支均合法, 仲裁: [分界条件] MergeBatch最优=False (k_L1=K(截断); b_core=4 vs 阈值 b0*(T_comp+T_write)/T_cmd=17.6; drain惩罚=(b0-1)*(T_comp+T_write)=0.44us, 搬移节省=b_core*(1-1/b0)*T_cmd=0.10us); [时延模型] T_MergeBatch=11.26us vs T_IterBatch=11.01us -> IterBatch更优; [裁决] IterBatch" merge_iter_arbitrate,128,128,64,64,512,bf16,bf16,bf16,False,False,False,True,0,merge_iter_arbitrate,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,512,512,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=256KB <= L1; 输出落点: L2驻留,16777216,0.0,1.048576e-05,0.0,1.0685759999999999e-05,4,2.0000000000000002e-07,536870912.0,1.104672658436214e-06,1048576,2.0164923076923077e-07,0.0,1.0685759999999999e-05,3.265804723013612e-07,1.101234047230136e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"两分支均合法, 仲裁: [分界条件] MergeBatch最优=False (L1绑定(k_l1^m=256<K=512); 每核命令数 MergeBatch=4 vs IterBatch=4, 搬移节省=0.00us vs drain惩罚=(b0-1)*(T_comp+T_write)=0.44us -> IterBatch优); [时延模型] T_MergeBatch=11.06us vs T_IterBatch=11.01us -> IterBatch更优; [裁决] IterBatch"
iter_demo_form_b,128,128,64,64,256,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_b,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,256,256,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=128KB <= L1; 输出落点: L2驻留,8388608,0.0,5.24288e-06,0.0,5.4428799999999995e-06,4,2.0000000000000002e-07,268435456.0,5.52336329218107e-07,1048576,2.0164923076923077e-07,0.0,5.4428799999999995e-06,1.8849638999683443e-07,5.631376389996834e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足 iter_demo_form_b,128,128,64,64,256,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_b,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,64,64,256,256,2,b_双batch乒乓,64,64,256,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,双batch乒乓: 2*(MK+KN)*dtype=128KB <= L1; 输出落点: L2驻留,8388608,0.0,5.24288e-06,0.0,5.4428799999999995e-06,4,2.0000000000000002e-07,268435456.0,5.52336329218107e-07,1048576,2.0164923076923077e-07,0.0,5.4428799999999995e-06,1.8849638999683443e-07,5.631376389996834e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
iter_demo_form_d,64,64,64,64,8192,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_d,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,64,64,8192,1024,1,d_两侧都切K,64,64,256,allocate(GM->L1随路驻留L2),"direct_gm(整case超L2: 输入优先驻留L2, 输出直写GM不占L2)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: 直写GM",134217728,0.0,8.388608e-05,0.0,8.468608e-05,16,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,524288,3.2768e-07,0.0,8.501376e-05,7.16176329218107e-07,8.572993632921812e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足 iter_demo_form_d,64,64,64,64,8192,bf16,bf16,bf16,False,False,False,True,0,iter_demo_form_d,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,64,64,8192,1024,1,d_两侧都切K,64,64,256,allocate(GM->L1随路驻留L2),"direct_gm(整case超L2: 输入优先驻留L2, 输出直写GM不占L2)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: 直写GM",134217728,0.0,8.388608e-05,0.0,8.468608e-05,16,8.000000000000001e-07,4294967296.0,8.837381267489712e-06,524288,3.2768e-07,0.0,8.501376e-05,7.16176329218107e-07,8.572993632921812e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
streamk_demo,4,4,128,128,10240,bf16,bf16,bf16,False,False,False,True,0,streamk_demo,StreamK,Ascend950PR,batch_mat_mul_v3,32,1,1,1,32,"B/M/N切出4块, 每块32核切K归约 (归约组内核c负责K段[c*K/32,(c+1)*K/32))",1,1,128,128,320,256,1,K段标准分块流水,128,128,64,allocate(部分和驻留L2),"resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换)",0,8388608,grid_K=32路切K+归约,1,1,32,0,0,0,0,True,4,"P=1.00, grid_K=32, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终",20971520,0,1.31072e-05,0.0,1.31072e-05,0.0,0.0,1342177280.0,2.761681646090535e-06,0.0,0.0,3.4067453613053613e-06,1.31072e-05,3.4067453613053613e-06,1.651394536130536e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"P<=C/2, B/M/N并行度买不满, 切K (grid_K=32)" streamk_demo,4,4,128,128,10240,bf16,bf16,bf16,False,False,False,True,0,streamk_demo,StreamK,Ascend950PR,batch_mat_mul_v3,32,1,1,1,32,"B/M/N切出4块, 每块32核切K归约 (归约组内核c负责K段[c*K/32,(c+1)*K/32))",1,1,128,128,320,256,1,K段标准分块流水,128,128,64,allocate(部分和驻留L2),"resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换)",0,8388608,grid_K=32路切K+归约,1,1,32,0,0,0,0,True,4,"P=1.00, grid_K=32, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终",20971520,0,1.31072e-05,0.0,1.31072e-05,0.0,0.0,1342177280.0,2.761681646090535e-06,0.0,0.0,3.4067453613053613e-06,1.31072e-05,3.4067453613053613e-06,1.651394536130536e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"P<=C/2, B/M/N并行度买不满, 切K (grid_K=32)"
1 case_id batch_a batch_b m n k dtype_a dtype_b dtype_c trans_a trans_b has_bias out_nd deterministic_level plan_case_id plan_branch plan_npu plan_op plan_used_core_num plan_split_b plan_m_cnt plan_n_cnt plan_grid_k plan_core_map plan_b_core plan_merge_b0 plan_single_core_m plan_single_core_n plan_single_core_k plan_k_l1 plan_b_l1 plan_l1_form plan_base_m plan_base_n plan_base_k plan_l2_policy_in plan_l2_policy_out plan_swizzle_w plan_workspace_bytes plan_tail_strategy plan_tail_m_cnt plan_tail_n_cnt plan_tail_k_cnt plan_tail_m_main plan_tail_n_main plan_tail_block_cnt plan_tail_wave_num plan_fixpipe_unitflag plan_out_dtype_bytes plan_note gm_read_bytes l2_read_bytes t_mte2_gm t_mte2_l2 t_mte2 dma_cmd_count t_dma_cmd cube_flops t_mmad fixpipe_bytes t_fixpipe t_reduce t_steady t_drain t_total bottleneck feasible violations bound_type advice
2 to_matmul_demo 1 1 2048 2048 2048 bf16 bf16 bf16 False False False True 0 to_matmul_demo 转Matmul Ascend950PR batch_mat_mul_v3 32 1 0 0 1 折叠为 Matmul [2048,2048]x[2048,2048], 复用 Matmul 切分体系 0 1 0 0 2048 0 1 0 0 0 0 0 转Matmul后由 Matmul 体系决定 1 1 1 0 0 0 0 True 2 BatchB=1免费折叠: 左矩阵 [1,2048,2048] 视图折叠为 [2048,2048], 零重排零 split 16777216 0.0 1.048576e-05 0.0 1.048576e-05 0.0 0.0 17179869184.0 3.534952506995885e-05 8388608 1.6131938461538462e-06 0.0 3.534952506995885e-05 0.0 3.534952506995885e-05 MMAD True 计算Bound BatchA=1或BatchB=1, 折叠转普通Matmul
3 special_k0_demo 128 128 256 256 0 bf16 bf16 bf16 False False False True 0 special_k0_demo 特殊分支 Ascend950PR batch_mat_mul_v3 64 1 1 1 1 AIV 核间按行均分 (无 Cube tile 概念) 0 1 0 0 0 0 1 UB驻留(AIV) 0 0 0 allocate direct_gm 0 0 不涉及(AIV逐元素) 1 1 1 0 0 0 0 False 2 K=0纯写值: 无任何计算, C=bias 或 0, 纯 AIV 写值; 按行均分到 AIV 核 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 16777216 3.2263876923076923e-06 0.0 3.2263876923076923e-06 0.0 3.2263876923076923e-06 FIXPIPE True 写出Bound(L2写口) K=0纯写值
4 special_k1_demo 128 128 256 256 1 bf16 bf16 bf16 False False False True 0 special_k1_demo 特殊分支 Ascend950PR batch_mat_mul_v3 64 1 1 1 1 AIV 核间按行均分 (无 Cube tile 概念) 0 1 0 0 1 0 1 UB驻留(AIV) UB乒乓 0 0 0 allocate direct_gm 0 0 不涉及(AIV逐元素) 1 1 1 0 0 0 0 False 2 K=1逐元素乘: 退化为 C=A⊙B 无累加深度, Cube 16x16x16 粒度浪费 15/16; 走 AIV 通路 GM->UB->Mul->GM, UB乒乓 (B>=2*AIV 双batch乒乓流水) 131072 0.0 8.192e-08 0.0 8.192e-08 0.0 0.0 8388608.0 3.103030303030303e-07 16777216 3.2263876923076923e-06 0.0 3.2263876923076923e-06 0.0 3.2263876923076923e-06 FIXPIPE True 写出Bound(L2写口) K=1逐元素乘, 走AIV向量通路
5 merge_demo_k_trunc 2048 2048 32 32 256 bf16 bf16 bf16 False False False True 0 merge_demo_k_trunc MergeBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B均分(核间零重复读零依赖) 64 4 128 128 256 256 8 合并驻留 128 128 128 allocate(GM->L1随路驻留L2) resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 b0=4 (L0C上限5.7/算存比上限19.0/b_core=64); K截断; 合并后单次DMA搬入 A'[128,256]+B'[256,128]; 输出落点: L2驻留 (整case V_in+V_out=64.0MB vs L2=128MB) 67108864 0.0 4.194304e-05 0.0 4.2743039999999997e-05 16.0 16 8.000000000000001e-07 4294967296.0 8.837381267489712e-06 4194304 8.065969230769231e-07 0.0 4.2743039999999997e-05 1.8849638999683443e-07 4.293153638999683e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) 两分支均合法, 仲裁: [分界条件] MergeBatch最优=True (k_L1=K(截断); b_core=64 vs 阈值 b0*(T_comp+T_write)/T_cmd=6.0; drain惩罚=(b0-1)*(T_comp+T_write)=0.23us, 搬移节省=b_core*(1-1/b0)*T_cmd=2.40us); [时延模型] T_MergeBatch=42.93us vs T_IterBatch=45.19us -> MergeBatch更优; [裁决] MergeBatch 两分支均合法, 仲裁: [分界条件] MergeBatch最优=True (K截断(k_l1^m=256>=K); 每核命令数 MergeBatch=16 vs IterBatch=64, 搬移节省=2.40us vs drain惩罚=(b0-1)*(T_comp+T_write)=0.23us -> MergeBatch优 (闭式等价: b_core=64 vs 阈值 b0*(T_comp+T_write)/T_cmd=6.0)); [时延模型] T_MergeBatch=42.93us vs T_IterBatch=45.19us -> MergeBatch更优; [裁决] MergeBatch
6 merge_iter_arbitrate 128 128 64 64 512 bf16 bf16 bf16 False False False True 0 merge_iter_arbitrate IterBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B轮转分配(核间零重复读零依赖) 4 1 64 64 512 512 2 b_双batch乒乓 64 64 256 allocate(GM->L1随路驻留L2) resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 双batch乒乓: 2*(MK+KN)*dtype=256KB <= L1; 输出落点: L2驻留 16777216 0.0 1.048576e-05 0.0 1.0685759999999999e-05 4 2.0000000000000002e-07 536870912.0 1.104672658436214e-06 1048576 2.0164923076923077e-07 0.0 1.0685759999999999e-05 3.265804723013612e-07 1.101234047230136e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) 两分支均合法, 仲裁: [分界条件] MergeBatch最优=False (k_L1=K(截断); b_core=4 vs 阈值 b0*(T_comp+T_write)/T_cmd=17.6; drain惩罚=(b0-1)*(T_comp+T_write)=0.44us, 搬移节省=b_core*(1-1/b0)*T_cmd=0.10us); [时延模型] T_MergeBatch=11.26us vs T_IterBatch=11.01us -> IterBatch更优; [裁决] IterBatch 两分支均合法, 仲裁: [分界条件] MergeBatch最优=False (L1绑定(k_l1^m=256<K=512); 每核命令数 MergeBatch=4 vs IterBatch=4, 搬移节省=0.00us vs drain惩罚=(b0-1)*(T_comp+T_write)=0.44us -> IterBatch优); [时延模型] T_MergeBatch=11.06us vs T_IterBatch=11.01us -> IterBatch更优; [裁决] IterBatch
7 iter_demo_form_b 128 128 64 64 256 bf16 bf16 bf16 False False False True 0 iter_demo_form_b IterBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B轮转分配(核间零重复读零依赖) 4 1 64 64 256 256 2 b_双batch乒乓 64 64 256 allocate(GM->L1随路驻留L2) resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 双batch乒乓: 2*(MK+KN)*dtype=128KB <= L1; 输出落点: L2驻留 8388608 0.0 5.24288e-06 0.0 5.4428799999999995e-06 4 2.0000000000000002e-07 268435456.0 5.52336329218107e-07 1048576 2.0164923076923077e-07 0.0 5.4428799999999995e-06 1.8849638999683443e-07 5.631376389996834e-06 MTE2 True 访存Bound(GM读写共享+L2重复读) 仅 IterBatch 条件满足
8 iter_demo_form_d 64 64 64 64 8192 bf16 bf16 bf16 False False False True 0 iter_demo_form_d IterBatch Ascend950PR batch_mat_mul_v3 32 32 1 1 1 切B轮转分配(核间零重复读零依赖) 2 1 64 64 8192 1024 1 d_两侧都切K 64 64 256 allocate(GM->L1随路驻留L2) direct_gm(整case超L2: 输入优先驻留L2, 输出直写GM不占L2) 0 0 不涉及(核内不切M/N) 1 1 1 0 0 0 0 True 2 两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: 直写GM 134217728 0.0 8.388608e-05 0.0 8.468608e-05 16 8.000000000000001e-07 4294967296.0 8.837381267489712e-06 524288 3.2768e-07 0.0 8.501376e-05 7.16176329218107e-07 8.572993632921812e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) 仅 IterBatch 条件满足
9 streamk_demo 4 4 128 128 10240 bf16 bf16 bf16 False False False True 0 streamk_demo StreamK Ascend950PR batch_mat_mul_v3 32 1 1 1 32 B/M/N切出4块, 每块32核切K归约 (归约组内核c负责K段[c*K/32,(c+1)*K/32)) 1 1 128 128 320 256 1 K段标准分块流水 128 128 64 allocate(部分和驻留L2) resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换) 0 8388608 grid_K=32路切K+归约 1 1 32 0 0 0 0 True 4 P=1.00, grid_K=32, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终 20971520 0 1.31072e-05 0.0 1.31072e-05 0.0 0.0 1342177280.0 2.761681646090535e-06 0.0 0.0 3.4067453613053613e-06 1.31072e-05 3.4067453613053613e-06 1.651394536130536e-05 MTE2 True 访存Bound(GM读写共享+L2重复读) P<=C/2, B/M/N并行度买不满, 切K (grid_K=32)

View File

@@ -388,18 +388,21 @@ class TestZeroCmdHandling(unittest.TestCase):
"""T_cmd=0 (无命令时延/未标定) 时整链路不得除零/崩溃, 按策略优先 MergeBatch.""" """T_cmd=0 (无命令时延/未标定) 时整链路不得除零/崩溃, 按策略优先 MergeBatch."""
def test_beats_iterbatch_policy(self): def test_beats_iterbatch_policy(self):
# T_cmd<=0: 阈值 +inf 不可除零; K截断按策略判 MergeBatch 胜 (指令级收益未量化), # T_cmd<=0: 阈值 +inf 不可除零; 合并后每核命令数更少即按策略判 MergeBatch 胜
# L1 绑定仍恒劣 # (指令级收益未建模), 命令数打平/更多则恒劣 (issue#35 泛化口径)
from bmm_theory.hardware import NpuSpec from bmm_theory.hardware import NpuSpec
from bmm_theory.branches.merge_batch import MergeBatchBranch from bmm_theory.branches.merge_batch import MergeBatchBranch
spec0 = NpuSpec(t_cmd_ns=0.0) spec0 = NpuSpec(t_cmd_ns=0.0)
mb = MergeBatchBranch(spec0) mb = MergeBatchBranch(spec0)
# (b, m, n, k, K截断与否) # (b, m, n, k, MergeBatch应胜与否=合并后命令数更少)
cases = [(2048, 32, 32, 256, True), (128, 64, 64, 512, True), # (128,64,64,512): issue#35 —— 合并侧被 dValue 512B cap 截断 (k_l1^m=256,
# n_K^m=2), 而 IterBatch 走 b 形态 k_l1=K=512, 每核命令数 4=4 打平, 合并只
# 放大 drain -> 恒劣; 原期望 True 建立在未合并口径的误分类上 (第三情形)
cases = [(2048, 32, 32, 256, True), (128, 64, 64, 512, False),
(256, 128, 128, 4096, False)] (256, 128, 128, 4096, False)]
for b, m, n, k, truncated in cases: for b, m, n, k, mb_wins in cases:
win, detail = mb.beats_iterbatch(mkcase(b, m, n, k)) win, detail = mb.beats_iterbatch(mkcase(b, m, n, k))
self.assertEqual(win, truncated, f"{b},{m},{n},{k}: {detail}") self.assertEqual(win, mb_wins, f"{b},{m},{n},{k}: {detail}")
self.assertIn("T_cmd=0", detail) self.assertIn("T_cmd=0", detail)
def test_route_with_zero_cmd_prefers_merge(self): def test_route_with_zero_cmd_prefers_merge(self):
@@ -798,5 +801,71 @@ class TestIssue33(unittest.TestCase):
self.assertTrue(er.feasible) self.assertTrue(er.feasible)
class TestIssue35(unittest.TestCase):
"""issue#35: MergeBatch L1 绑定情形 DMA 命令数多计 b0 倍修复 + 分界泛化口径.
用户 case 家族: B=128, M=1~16, N=128, K=512, bf16. b_core=4, b0=4,
合并后 k_l1^m=240/224 < K=512 (L1 绑定区), 真实每核命令数 = 1x3=3 条
(< IterBatch 的 4 条), 修复前被多计为 12 条导致仲裁翻错方向.
"""
def setUp(self):
self.router = BranchRouter()
self.mb = MergeBatchBranch()
self.ib = IterBatchBranch()
def test_merged_cmd_count_formula(self):
# 每核命令数 = ceil(b_core/b0) * ceil(K/k_l1^m) (K截断时 = b_core/b0)
case = mkcase(128, 16, 128, 512)
r = self.mb.analyze(case)
self.assertTrue(r.capable)
p = r.plan
expect = -(-p.b_core // p.merge_b0) * (-(-case.k // p.k_l1))
self.assertEqual(r.timing.dma_cmd_count, expect)
# 本 case: b0=4, k_l1=224 -> 1*3 = 3 条 (修复前 12 条)
self.assertEqual((p.merge_b0, p.k_l1), (4, 224))
self.assertEqual(r.timing.dma_cmd_count, 3)
def test_cmd_count_truncated_unchanged(self):
# K 截断情形数值不变: cmds = b_core/b0 = IterBatch 的 1/b0
case = mkcase(2048, 32, 32, 256)
mb = self.mb.analyze(case)
ib = self.ib.analyze(case)
self.assertGreaterEqual(mb.plan.k_l1, case.k) # 合并后仍截断
self.assertEqual(mb.timing.dma_cmd_count,
-(-mb.plan.b_core // mb.plan.merge_b0))
self.assertAlmostEqual(
mb.timing.dma_cmd_count / ib.timing.dma_cmd_count,
1.0 / mb.plan.merge_b0, places=6)
def test_boundary_uses_merged_k_l1(self):
# 截断判定与 plan.k_l1 口径一致: k_l1^m < K 时不得声称 K截断
case = mkcase(128, 1, 128, 512)
_, detail = self.mb.beats_iterbatch(case)
p = self.mb.make_plan(case)
self.assertLess(p.k_l1, case.k)
self.assertIn("L1绑定", detail)
self.assertNotIn("K截断", detail)
def test_user_case_family_routing(self):
# B=128,M=1~16,N=128,K=512: 修复后小 M 由 MergeBatch 胜 (命令节省 >
# drain 惩罚), 大 M 由 IterBatch 胜 (drain 随 M 增长, 节省固定)
expect = {1: "MergeBatch", 2: "MergeBatch", 4: "MergeBatch",
8: "IterBatch", 16: "IterBatch"}
for m, branch in expect.items():
r = self.router.route(mkcase(128, m, 128, 512))
self.assertEqual(r["branch"], branch, f"m={m}: {r['arbitration']}")
self.assertEqual(r["candidates"], {"MergeBatch": True, "IterBatch": True})
self.assertEqual(r["self_check_violations"], [])
def test_arbitration_text_final_winner_consistent(self):
# 仲裁文本 [裁决] 位必须是最终胜者 (分界与时延不一致时括注说明)
import re
r = self.router.route(mkcase(128, 2, 128, 512))
m = re.search(r"\[裁决\] (\w+)", r["arbitration"])
self.assertIsNotNone(m)
self.assertEqual(m.group(1), r["branch"])
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()