Fix #36: MergeBatch 合并搬移效率收益建模 (move_eff) + t_cmd_ns 置 0
用户澄清: MergeBatch vs IterBatch 的本质区别不只是 DMA 命令数 —— 合并 b0 个 batch 的左/右矩阵一起搬入 L1, 使单块 tile = nValue*dValue*dt 放大 b0 倍 (堆叠 方向视转置: A ND 非转置沿 M(nValue), B ND 非转置沿 N(dValue)), 搬移效率更高, 即便 T_cmd=0 也有效益。 - models.move_eff: 单命令搬移效率 eff = min(1, tile/min_TileSize) (16KB 饱和, 与进入条件4效率下限语义同源); gm_move_time 按 A/B 两侧字节加权 t = (V_A/eff_A + V_B/eff_B)/BW_gm; 只影响时间列, GM 字节量仍 = V_in - IterBatch: l1_form 补驻留侧返回; move_tiles 分侧口径 (a/b 双侧整K, c 驻留侧 整K+对侧k_l1, d 双侧k_l1), evaluate 接入效率加权 - MergeBatch: 合并 tile 放大 b0 倍接入效率加权; beats_iterbatch 净收益 = 命令节省(cmds差×T_cmd) + 效率节省(t_data差) − drain惩罚, K截断且效率打平且 T_cmd>0 时严格退化为 v1.1 §4.5 闭式; 退役 T_cmd<=0 策略特判 - router: 退役 "T_cmd<=0 策略优先 MergeBatch" 覆盖, 时延模型统一终审 - hardware: t_cmd_ns 50 -> 0 (未标定按 0; 合并收益不再依赖 T_cmd 估计值) - 作用域: 仅切B 两分支接入 (逐命令 tile 小、效率差显著); ASW/StreamK 单命令 tile 通常已饱和, 极端小 tile 走 issue#34 效率降级标注通道 - 用户 case 家族 B=128,M=1~16,N=128,K=512: m=1~8 -> MergeBatch (效率节省 ~0.61us > drain), m=16 -> IterBatch (iter A tile 恰达 16KB 饱和, 效率打平, drain 决定); 分界与时延全家族一致 - demo: merge_demo_k_trunc 形状 (2048,32,32,256)->(2048,16,64,128) (原形状 两侧 tile 均已 16KB 饱和, t_cmd=0 下无收益转 IterBatch; 新形状 iter A tile 4KB eff=0.25 vs 合并 16KB eff=1.0, 保持 MergeBatch 胜出演示且仍 K截断) - 测试: 74/74 (新增 TestIssue36 5 例: 效率曲线/字节不变/效率差胜出/家族; TestArbitration/TestZeroCmdHandling 按 t_cmd=0+效率语义重写; TestIssue35 家族期望更新) - 文档: 01_MergeBatch §4/§5 效率模型+泛化净收益; 02_IterBatch 口径注; 00_总纲胜出条件; 01_软件架构 T_cmd 标定说明; 05 时间列效率口径注; README 要点 - 验证: examples 重生成可复现 0 diff; 压力 10000 例 0 崩溃/0 NaN/0 违规/ 0 GM<V_in, 七分支覆盖 (MergeBatch 386 例)
This commit is contained in:
@@ -50,7 +50,8 @@ python -m unittest discover -s tests -v
|
||||
### 时延模型要点 (读结果前必看)
|
||||
|
||||
- **GM 是读写共享总线 (1.6TB/s)**: MTE2 的 GM 读与 Fixpipe 直写 GM 并发时按 **(读+写)/1.6TB/s 累加**计入 MTE2 搬移链 (issue#23);
|
||||
- **搬入 MTE2 分两段、同链相加**: `t_mte2_gm` (首读按 GM 带宽; 随路驻留 L2 不重复累加) + `t_mte2_l2` (共享块驻留 L2 后被其它核重复读, 按 L2 读口 5.2TB/s) + DMA 命令开销 (issue#24);
|
||||
- **搬入 MTE2 分两段、同链相加**: `t_mte2_gm` (首读按 GM 带宽; 随路驻留 L2 不重复累加) + `t_mte2_l2` (共享块驻留 L2 后被其它核重复读, 按 L2 读口 5.2TB/s) + DMA 命令开销 (issue#24; **T_cmd 默认 0**, 未标定按 0 处理, issue#36);
|
||||
- **搬移效率模型 (issue#36)**: 切B 两分支 (IterBatch/MergeBatch) 的 GM→L1 数据时延按单命令 tile 效率加权 —— eff = min(1, tile/min_TileSize), tile = nValue×dValue×dtype 达 16KB 饱和; **MergeBatch 合并 b0 个 batch 使单块 tile 放大 b0 倍, 即便 T_cmd=0 也比 IterBatch 逐 batch 搬移效率高** (堆叠方向视转置: A ND 非转置沿 M(nValue), B ND 非转置沿 N(dValue)); 只影响时间列, GM 字节量不变;
|
||||
- **Cube 计算** `t_mmad`: 芯片算力 ≈486 TFLOPS (单核 ≈15.2 TFLOPS), MergeBatch 冗余计算计入;
|
||||
- **Fixpipe 搬出**: 直写 GM 计入 GM 共享总线; 驻留 L2 走 5.2TB/s 写口 (独立计时); 数据量按 **C 矩阵 dtype** 计 (fp16/fp8 随路转换减半); StreamK 部分和按 4B (L0C dtype);
|
||||
- **总时延** `t_total = max(MTE2搬移链, MMAD, Fixpipe-L2) + t_drain` (稳态取最大 + 末级排空暴露; REDUCE 串行追加);
|
||||
|
||||
@@ -12,7 +12,7 @@ batch 间流水靠 L1 双 buffer / 驻留侧预取 (c 形态半预算) 掩盖.
|
||||
from __future__ import annotations
|
||||
|
||||
from ..hardware import NpuSpec, ASCEND950PR
|
||||
from ..models import BmmCase, ImplPlan, HardwareTiming, align_down
|
||||
from ..models import BmmCase, ImplPlan, HardwareTiming, align_down, gm_move_time
|
||||
from ..timing import assemble_timing, output_to_l2
|
||||
from .base import Branch, BranchResult, ConditionCheck
|
||||
|
||||
@@ -23,11 +23,34 @@ class IterBatchBranch(Branch):
|
||||
def __init__(self, spec: NpuSpec = ASCEND950PR):
|
||||
super().__init__(spec)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 单命令搬移 tile (issue#36 效率模型口径, evaluate 与 MergeBatch 仲裁共用)
|
||||
# ------------------------------------------------------------------
|
||||
def move_tiles(self, case: BmmCase) -> tuple:
|
||||
"""返回 (A侧单命令tile字节, B侧单命令tile字节).
|
||||
|
||||
a/b 形态: 双侧整 K 一次搬入; c 形态: 驻留侧整 K + 对侧 k_l1 分块;
|
||||
d 形态: 双侧 k_l1 分块。tile = nValue*dValue*dt (乘积与转置/排布无关)。
|
||||
"""
|
||||
m, n, k = case.m, case.n, case.k
|
||||
dt = case.dtype_in_bytes
|
||||
form, k_l1, _, resident = self.l1_form(case)
|
||||
if form in ("a", "b"):
|
||||
return m * k * dt, k * n * dt
|
||||
if form == "c":
|
||||
return (m * k * dt, k_l1 * n * dt) if resident == "A" \
|
||||
else (m * k_l1 * dt, k * n * dt)
|
||||
return m * k_l1 * dt, k_l1 * n * dt # d 或 None (兜底)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# L1 驻留形态判定 (v0.98 §六 条件 3, 四选一)
|
||||
# ------------------------------------------------------------------
|
||||
def l1_form(self, case: BmmCase) -> tuple:
|
||||
"""返回 (形态 'a'/'b'/'c'/'d'/None, k_l1, 说明)."""
|
||||
"""返回 (形态 'a'/'b'/'c'/'d'/None, k_l1, 说明, 驻留侧 'A'/'B'/None).
|
||||
|
||||
驻留侧仅 c 形态非 None (issue#36: 效率模型需要区分两侧单命令 tile —
|
||||
c 形态驻留侧整侧一次搬入 (全 K), 对侧按 k_l1 分块).
|
||||
"""
|
||||
s = self.spec
|
||||
m, n, k = case.m, case.n, case.k
|
||||
dt = case.dtype_in_bytes
|
||||
@@ -36,11 +59,11 @@ class IterBatchBranch(Branch):
|
||||
|
||||
# a) 单 batch 全驻留
|
||||
if b_core == 1 and single <= s.l1_bytes:
|
||||
return "a", k, f"单batch全驻留: (MK+KN)*dtype={single/1024:.0f}KB <= L1"
|
||||
return "a", k, f"单batch全驻留: (MK+KN)*dtype={single/1024:.0f}KB <= L1", None
|
||||
|
||||
# b) 双 batch 乒乓
|
||||
if b_core > 1 and 2 * single <= s.l1_bytes:
|
||||
return "b", k, f"双batch乒乓: 2*(MK+KN)*dtype={2*single/1024:.0f}KB <= L1"
|
||||
return "b", k, f"双batch乒乓: 2*(MK+KN)*dtype={2*single/1024:.0f}KB <= L1", None
|
||||
|
||||
# c) 一侧驻留 + 对侧切 K, 预算按 b_core 分档
|
||||
# dValue 守卫与条件 4 / constraints 同源 (issue#19): 转置感知连续维判据
|
||||
@@ -61,7 +84,7 @@ class IterBatchBranch(Branch):
|
||||
return "c", k_l1, (
|
||||
f"一侧驻留({side})+对侧切K: {side}驻留{resident/1024:.0f}KB, "
|
||||
f"预算L1/{min(b_core,2)}, k_L1={k_l1}, "
|
||||
f"dValueA={dv_a:.0f}B/dValueB={dv_b:.0f}B")
|
||||
f"dValueA={dv_a:.0f}B/dValueB={dv_b:.0f}B"), side
|
||||
# b_core>=2 时另一半 L1 预取下一 batch 驻留侧, 边界无气泡
|
||||
|
||||
# d) 两侧都切 K (兜底)
|
||||
@@ -69,9 +92,9 @@ class IterBatchBranch(Branch):
|
||||
dv_a, dv_b = dvalue_contig_dims(case, k_l1)
|
||||
if (k_l1 >= s.fractal and dv_a >= s.dvalue_min and dv_b >= s.dvalue_min):
|
||||
return "d", k_l1, (f"两侧都切K: k_L1={k_l1}, K段成对流水, batch边界天然无缝; "
|
||||
f"dValueA={dv_a:.0f}B/dValueB={dv_b:.0f}B")
|
||||
f"dValueA={dv_a:.0f}B/dValueB={dv_b:.0f}B"), None
|
||||
|
||||
return None, 0, "L1 四形态均不满足 (M/N 相对 L1 过大)"
|
||||
return None, 0, "L1 四形态均不满足 (M/N 相对 L1 过大)", None
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 进入条件 (v0.98 §六, 四条同时满足)
|
||||
@@ -95,7 +118,7 @@ class IterBatchBranch(Branch):
|
||||
"2_负载均衡: B mod C == 0 或 >= minCoreNum",
|
||||
c2, f"B mod C={rem}, minCoreNum={s.min_core_num}"))
|
||||
|
||||
form, k_l1, form_desc = self.l1_form(case)
|
||||
form, k_l1, form_desc, _resident = self.l1_form(case)
|
||||
checks.append(ConditionCheck(
|
||||
"3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读)",
|
||||
form is not None, form_desc))
|
||||
@@ -131,7 +154,7 @@ class IterBatchBranch(Branch):
|
||||
m, n, k = case.m, case.n, case.k
|
||||
dt = case.dtype_in_bytes
|
||||
b_core = -(-case.batch_c // s.aic_num)
|
||||
form, k_l1, form_desc = self.l1_form(case)
|
||||
form, k_l1, form_desc, _resident = self.l1_form(case)
|
||||
form = form or "d"
|
||||
|
||||
# L0 级 tile (BaseM x BaseN): 核内 L1->L0 的切分, 与核间切分无关.
|
||||
@@ -223,7 +246,11 @@ class IterBatchBranch(Branch):
|
||||
# n_K/k_L1 只决定 DMA 命令次数 (T_cmd) 与双缓冲调度, 不放大数据量.
|
||||
# dma_cmds 为单核命令数 (各核并行, issue#29 口径)
|
||||
dma_cmds = b_core * n_k
|
||||
t_mte2_data = case.input_bytes / s.bw_gm
|
||||
# 搬移效率 (issue#36): 单命令 tile = nValue*dValue*dt 决定有效带宽
|
||||
# (达 min_TileSize 饱和, 之下线性退化), 分侧口径见 move_tiles
|
||||
tile_a, tile_b = self.move_tiles(case)
|
||||
t_mte2_data = gm_move_time(b * m * k * dt, b * k * n * dt,
|
||||
tile_a, tile_b, s)
|
||||
t_dma_cmd = dma_cmds * s.t_cmd
|
||||
t_mte2 = t_mte2_data + t_dma_cmd
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
- 《BMM算子优化分析 v0.98》§五 (进入条件 + 实现方案 Step1~3)
|
||||
- 《MergeBatch_vs_IterBatch分析 v1.1》§三/§四 (执行模型 + 分界条件)
|
||||
|
||||
核心思想: 合并 b0 个 batch 的 A'[b0*M,K] @ B'[K,b0*N] 为单次 DMA 搬入,
|
||||
减少 GM->L1 搬移命令数 (省 b0 倍 T_cmd); 交叉项被算出但丢弃 (冗余比例 (b0-1)/b0),
|
||||
进入条件 5 保证 case 为访存 Bound, 冗余算力被搬移时延掩盖.
|
||||
T_cmd=0 时 (无命令固定时延/未标定) 命令时延收益不可量化, 但合并仍可减少
|
||||
搬移命令/主机指令数 (指令发射/调度/同步收益未建模) —— beats_iterbatch 按既定
|
||||
策略裁决: 合并后实际每核命令数更少即优先 MergeBatch (模型内代价仅 drain 惩罚),
|
||||
命令数打平恒劣 (issue#35 泛化口径, 覆盖 dValue 512B cap 截断等第三情形).
|
||||
核心思想: 合并 b0 个 batch 的 A'[b0*M,K] @ B'[K,b0*N] 为单次 DMA 搬入。
|
||||
合并的核心收益有二 (用户澄清, issue#36): (1) 搬移命令数减少 (省 T_cmd);
|
||||
(2) **单块 tile = nValue*dValue*dt 放大 b0 倍 -> 搬移效率提升** (堆叠方向视
|
||||
转置/排布: A ND 非转置沿 M(nValue) 堆叠, B ND 非转置沿 N(dValue) 堆叠) ——
|
||||
即便 T_cmd=0 (950PR 默认, 未标定按 0) 收益依然成立, 由 move_eff 效率模型刻画。
|
||||
核心劣势是交叉项冗余算力 ((b0-1)/b0 被算出但丢弃) 与 drain 暴露放大 b0 倍;
|
||||
进入条件 5 保证 case 为访存 Bound, 冗余算力被搬移时延掩盖。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -18,7 +18,7 @@ from __future__ import annotations
|
||||
import math
|
||||
|
||||
from ..hardware import NpuSpec, ASCEND950PR
|
||||
from ..models import BmmCase, ImplPlan, HardwareTiming, align_down
|
||||
from ..models import BmmCase, ImplPlan, HardwareTiming, align_down, gm_move_time
|
||||
from ..timing import assemble_timing, output_to_l2
|
||||
from .base import Branch, BranchResult, ConditionCheck
|
||||
|
||||
@@ -212,7 +212,12 @@ class MergeBatchBranch(Branch):
|
||||
n_k = -(-k // k_l1)
|
||||
dma_cmds = -(-b_core // b0) * n_k
|
||||
t_dma_cmd = dma_cmds * s.t_cmd
|
||||
t_mte2_data = case.input_bytes / s.bw_gm
|
||||
# 搬移效率 (issue#36, 用户澄清): 合并 b0 个 batch 使单命令 tile 放大 b0 倍
|
||||
# (A': b0*M x k_l1^m, B': k_l1^m x b0*N; 堆叠方向视转置/排布, 乘积不变),
|
||||
# 小 M/N case 下相对 IterBatch 逐 batch 搬移的效率收益显著, T_cmd=0 时仍成立
|
||||
k_eff = min(k_l1, k)
|
||||
t_mte2_data = gm_move_time(b * m * k * dt, b * k * n * dt,
|
||||
b0 * m * k_eff * dt, b0 * n * k_eff * dt, s)
|
||||
t_mte2 = t_mte2_data + t_dma_cmd
|
||||
|
||||
# Cube (每核口径): 合并计算含冗余 (b0^2 输出, 有效 b0), 每核 b_core/b0 步,
|
||||
@@ -244,18 +249,19 @@ class MergeBatchBranch(Branch):
|
||||
def beats_iterbatch(self, case: BmmCase) -> tuple:
|
||||
"""返回 (MergeBatch是否更优, 说明).
|
||||
|
||||
v1.1 §4.5 统一分界的泛化口径 (issue#35): 直接比较两分支**实际每核 DMA
|
||||
命令数**与 drain 惩罚 ——
|
||||
v1.1 §4.5 统一分界的泛化口径 (issue#35 命令数 / issue#36 搬移效率):
|
||||
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
|
||||
命令节省 = (cmds_iter - cmds_mb) * T_cmd
|
||||
效率节省 = t_data_iter - t_data_mb (合并放大单块 tile b0 倍 ->
|
||||
搬移效率提升, issue#36 用户澄清: 即便 T_cmd=0 也有收益)
|
||||
drain 惩罚 = (b0-1) * (T_comp + T_write) (T_comp 按未合并基线分块)
|
||||
MergeBatch 最优 ⟺ 搬移节省 > drain 惩罚.
|
||||
MergeBatch 最优 ⟺ 命令节省 + 效率节省 > drain 惩罚.
|
||||
|
||||
与 v1.1 §4.5 闭式的等价性:
|
||||
与 v1.1 §4.5 闭式的等价性 (T_cmd>0 且效率打平时):
|
||||
- K 截断 (k_l1^m = K): cmds_mb = b_core/b0, 退化为文档闭式
|
||||
b_core > b0*(T_comp+T_write)/T_cmd;
|
||||
- L1 绑定理想情形 (k_l1^m = k_l1^iter/b0): 命令数相同, 节省=0 -> 恒劣;
|
||||
- L1 绑定理想情形 (k_l1^m = k_l1^iter/b0): 命令数相同, 命令节省=0;
|
||||
- dValue 512B 推荐值截断等第三情形 (文档二分未覆盖): 按实际命令数比较.
|
||||
|
||||
截断判定用**合并后** plan.k_l1 >= K (与 make_plan/evaluate 同源,
|
||||
@@ -263,25 +269,30 @@ class MergeBatchBranch(Branch):
|
||||
且受 dValue 512B 推荐值截断), v1.1 line 219 的字面定义 (未合并口径) 与
|
||||
line 161 的合并公式矛盾时以后者为准.
|
||||
|
||||
T_cmd<=0 (无命令时延/未标定) 时阈值不可量化: 按既定策略, 合并后每核命令数
|
||||
更少 (cmds_mb < cmds_iter, 结构性指令/调度收益未建模) 即判 MergeBatch 优先;
|
||||
命令数打平则恒劣 (合并只放大 drain).
|
||||
T_cmd=0 (950PR 默认, 未标定): 命令节省项为 0, 由效率节省与 drain 惩罚
|
||||
决定 —— 合并 tile 放大带来的效率收益被显式建模, 不再需要"T_cmd<=0 时
|
||||
K截断即优先"的策略覆盖 (issue#36 退役)。
|
||||
"""
|
||||
s = self.spec
|
||||
m, n, k = case.m, case.n, case.k
|
||||
dt = case.dtype_in_bytes
|
||||
out_b = case.dtype_out_bytes
|
||||
b_core = case.batch_c // s.aic_num
|
||||
|
||||
# IterBatch 基线的每核命令数 (与 iter_batch.evaluate 同源: 形态 a/b 时
|
||||
# k_l1=K 一次一条; c/d 形态按 l1_form 判定的 k_l1 分段)
|
||||
# IterBatch 基线: 每核命令数 + 单命令 tile (与 iter_batch.evaluate 同源)
|
||||
from .iter_batch import IterBatchBranch
|
||||
_, k_l1_iter, _ = IterBatchBranch(s).l1_form(case)
|
||||
ib = IterBatchBranch(s)
|
||||
_, k_l1_iter, _, _ = ib.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
|
||||
tile_a_ib, tile_b_ib = ib.move_tiles(case)
|
||||
bb = case.batch_c
|
||||
t_data_ib = gm_move_time(bb * m * k * dt, bb * k * n * dt,
|
||||
tile_a_ib, tile_b_ib, s) # 整芯片口径 (量纲一致)
|
||||
|
||||
# MergeBatch 实际每核命令数 (issue#35: 合并组数 x 每组 K 段数)
|
||||
# MergeBatch 实际每核命令数 (issue#35) + 合并 tile (issue#36)
|
||||
plan = self.make_plan(case)
|
||||
b0 = plan.merge_b0
|
||||
n_k_mb = -(-k // min(plan.k_l1, k))
|
||||
@@ -289,6 +300,9 @@ class MergeBatchBranch(Branch):
|
||||
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})"
|
||||
k_eff = min(plan.k_l1, k)
|
||||
t_data_mb = gm_move_time(bb * m * k * dt, bb * k * n * dt,
|
||||
b0 * m * k_eff * dt, b0 * n * k_eff * dt, s)
|
||||
|
||||
# T_comp 按输入 dtype 算力 (issue#28), 未合并基线分块 (v1.1 §4.1 符号);
|
||||
# T_write 保持 v1.1 直写 GM 语义
|
||||
@@ -297,28 +311,15 @@ class MergeBatchBranch(Branch):
|
||||
t_write = m * n * out_b / s.bw_pc
|
||||
drain_pen = (b0 - 1) * (t_comp + t_write)
|
||||
save_cmds = cmds_iter - cmds_mb
|
||||
savings_cmd = save_cmds * s.t_cmd
|
||||
savings_eff = t_data_ib - t_data_mb
|
||||
|
||||
if s.t_cmd <= 0:
|
||||
# T_cmd=0: 命令时延收益不可量化 -> 按结构性命令数比较的策略裁决
|
||||
# (合并把搬移/计算命令序列并少, 指令发射/调度/同步收益存在但未量化);
|
||||
# 命令数打平时合并只放大 drain -> 恒劣.
|
||||
if cmds_mb < cmds_iter:
|
||||
detail = (f"{regime}; T_cmd=0: 命令时延收益不可量化(阈值=+inf), "
|
||||
f"合并后每核命令数 {cmds_mb} < IterBatch {cmds_iter} "
|
||||
f"(结构性收益, 未量化) -> 策略优先 MergeBatch; "
|
||||
f"模型内代价 drain 惩罚={drain_pen*1e6:.2f}us")
|
||||
return True, detail
|
||||
detail = (f"{regime}; T_cmd=0: 每核命令数 MergeBatch={cmds_mb} 不少于 "
|
||||
f"IterBatch={cmds_iter}, 合并只放大 drain 惩罚="
|
||||
f"{drain_pen*1e6:.2f}us -> 恒劣")
|
||||
return False, detail
|
||||
|
||||
savings = save_cmds * s.t_cmd
|
||||
win = savings > drain_pen
|
||||
detail = (f"{regime}; 每核命令数 MergeBatch={cmds_mb} vs IterBatch={cmds_iter}, "
|
||||
f"搬移节省={savings*1e6:.2f}us vs drain惩罚=(b0-1)*(T_comp+T_write)="
|
||||
win = (savings_cmd + savings_eff) > drain_pen
|
||||
detail = (f"{regime}; 每核命令数 MergeBatch={cmds_mb} vs IterBatch={cmds_iter} "
|
||||
f"(命令节省={savings_cmd*1e6:.2f}us) + 搬移效率节省="
|
||||
f"{savings_eff*1e6:.2f}us vs drain惩罚=(b0-1)*(T_comp+T_write)="
|
||||
f"{drain_pen*1e6:.2f}us -> {'MergeBatch优' if win else 'IterBatch优'}")
|
||||
if k_truncated:
|
||||
if k_truncated and s.t_cmd > 0:
|
||||
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
|
||||
|
||||
@@ -66,7 +66,11 @@ class NpuSpec:
|
||||
min_core_num_ratio: float = 0.8 # minCoreNum ≈ 0.8 * C (经验: 约 3/4 核并发才达 90%+ 带宽利用率)
|
||||
|
||||
# ---- DMA 固定开销 ----
|
||||
t_cmd_ns: float = 50.0 # T_cmd: 单次 GM->L1 DMA 命令固定开销 (ns, 估计值, 需实测标定)
|
||||
t_cmd_ns: float = 0.0 # T_cmd: 单次 GM->L1 DMA 命令固定开销 (ns)。
|
||||
# 未标定, 按 0 处理 (issue#36 用户澄清):
|
||||
# MergeBatch 的合并收益由搬移效率模型
|
||||
# (move_eff: 单块 tile=nValue*dValue*dt
|
||||
# 放大 b0 倍) 刻画, 不依赖 T_cmd 估计值.
|
||||
|
||||
# ---- 带宽模型假设 (issue#26) ----
|
||||
# GM 1.6TB/s 为读写共享总线 (读+写累加计时); L2 带宽读写各自独享 5.2TB/s;
|
||||
|
||||
@@ -72,6 +72,36 @@ def dvalue_contig_dims(case: "BmmCase", k_l1: float) -> tuple:
|
||||
return dv_a, dv_b
|
||||
|
||||
|
||||
def move_eff(tile_bytes: float, min_tile_size: int) -> float:
|
||||
"""GM->L1 单命令搬移效率 (issue#36, 用户澄清口径).
|
||||
|
||||
单命令搬移效率由单块 tile = nValue × dValue × input_dtype 决定: tile 越大,
|
||||
有效带宽越高; 达到 min_TileSize (16KB, 即进入条件 4 的效率下限常数) 饱和,
|
||||
之下线性退化 —— 与"max(MK,KN)·dt >= min_TileSize 才保证搬移效率"的语义同源
|
||||
(该条件只要求一侧达标, 另一侧小 tile 的低效由此函数量化)。
|
||||
|
||||
MergeBatch 合并 b0 个 batch 后单块 tile 放大 b0 倍 (A 侧: b0·M·k_l1·dt,
|
||||
B 侧: b0·N·k_l1·dt; 堆叠方向视转置/排布而定 —— A ND 非转置时沿 M(nValue)
|
||||
堆叠, B ND 非转置时沿 N(dValue) 堆叠, 乘积口径不变), 因此即便 T_cmd=0
|
||||
合并仍有搬移效率收益。
|
||||
"""
|
||||
if tile_bytes <= 0:
|
||||
return 1.0
|
||||
return min(1.0, tile_bytes / min_tile_size)
|
||||
|
||||
|
||||
def gm_move_time(v_a: float, v_b: float, tile_a: float, tile_b: float,
|
||||
spec) -> float:
|
||||
"""效率加权的 GM->L1 数据时延 (秒, 整芯片口径, issue#36).
|
||||
|
||||
t = (V_A/eff_A + V_B/eff_B) / BW_gm; 只影响**时间**列, GM 字节量不变
|
||||
(仍按每输入字节恰读一次 = V_in 计, issue#31)。
|
||||
"""
|
||||
ea = move_eff(tile_a, spec.min_tile_size)
|
||||
eb = move_eff(tile_b, spec.min_tile_size)
|
||||
return (v_a / ea + v_b / eb) / spec.bw_gm
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Case 输入
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
1. 前置归约: BatchA=1 或 BatchB=1 -> 转Matmul
|
||||
K=0 / K=1 -> 特殊分支 (AIV 向量通路)
|
||||
2. B >= C 且 BatchA==BatchB: 切B -> IterBatch 与 MergeBatch 仲裁
|
||||
仲裁规则 (v1.1 §4.5 统一分界):
|
||||
MergeBatch 最优 <=> K截断(k_L1=K) 且 b_core > b0*(T_comp+T_write)/T_cmd
|
||||
L1 绑定时 MergeBatch 恒劣于 IterBatch;
|
||||
两分支同时合法时用端到端时延模型 T_total 仲裁;
|
||||
例外: T_cmd<=0 (命令时延不可量化/未标定) 时, 指令级收益未建模,
|
||||
按既定策略: K截断即可优先 MergeBatch (覆盖时延模型仅来自 drain/冗余的差额).
|
||||
仲裁规则 (v1.1 §4.5 统一分界 + issue#35/#36 泛化):
|
||||
净收益 = 命令节省(cmds 差 × T_cmd) + 搬移效率节省(合并 tile 放大 b0 倍,
|
||||
move_eff 模型) − drain 惩罚; K截断且效率打平时退化为文档闭式
|
||||
b_core > b0*(T_comp+T_write)/T_cmd;
|
||||
两分支同时合法时用端到端时延模型 T_total 终审 (T_cmd 默认 0, 未标定;
|
||||
合并效率收益已建模, 不再需要策略覆盖).
|
||||
3. StreamK 检查: P <= C/2 且满足切K条件 -> StreamK (B/M/N 买不满时买 K)
|
||||
4. 兜底: ASW_Basic 切 M/N (含降核模式)
|
||||
"""
|
||||
@@ -86,26 +86,14 @@ class BranchRouter:
|
||||
|
||||
arbitration = ""
|
||||
if mb.capable and ib.capable:
|
||||
# 统一分界条件 + 端到端时延仲裁双保险
|
||||
# 统一分界条件 + 端到端时延仲裁双保险; 时延模型为最终裁决.
|
||||
# (issue#36: 合并的搬移效率收益已由 move_eff 模型量化进时延模型,
|
||||
# T_cmd=0 默认下不再需要"T_cmd<=0 策略优先 MergeBatch"的覆盖逻辑)
|
||||
mb_win, detail = self.merge_batch.beats_iterbatch(case)
|
||||
t_mb = mb.timing.t_total
|
||||
t_ib = ib.timing.t_total
|
||||
lat_win = self.merge_batch.name if t_mb <= t_ib else self.iter_batch.name
|
||||
win = self.merge_batch.name if mb_win else self.iter_batch.name
|
||||
# 冲突解决: 默认"时延模型为最终裁决"; 例外是 T_cmd<=0 且分界条件判
|
||||
# MergeBatch 胜 (K截断) 的情形 —— 此时时延模型不含指令级收益
|
||||
# (MergeBatch 搬移命令数/主机指令数省 b0 倍, 未量化), 按既定策略
|
||||
# 优先 MergeBatch (时延模型内的差额只是 drain 惩罚/冗余, 方向已知小量).
|
||||
policy_merge = (self.spec.t_cmd <= 0 and mb_win and
|
||||
win != lat_win and win == self.merge_batch.name)
|
||||
if policy_merge:
|
||||
arbitration = (
|
||||
f"两分支均合法, 仲裁: "
|
||||
f"[分界条件] MergeBatch最优={mb_win} ({detail}); "
|
||||
f"[时延模型] T_MergeBatch={t_mb*1e6:.2f}us vs T_IterBatch={t_ib*1e6:.2f}us -> {lat_win}更优; "
|
||||
f"[裁决] {win} (T_cmd<=0 策略: 命令/指令级收益未建模, 时延模型差异仅来自 "
|
||||
f"drain/冗余, 以 MergeBatch 优先策略裁决)")
|
||||
else:
|
||||
arbitration = (
|
||||
f"两分支均合法, 仲裁: "
|
||||
f"[分界条件] MergeBatch最优={mb_win} ({detail}); "
|
||||
|
||||
@@ -111,5 +111,5 @@ class Branch:
|
||||
|
||||
1. **转Matmul 精切**: 当前折叠后只粗估(`to_matmul.py::evaluate` 按 Matmul 总量),接入 MM 理论体系做精确切分。
|
||||
2. **换芯片**: 复制 `hardware/ascend950pr.py` 改常数,`NpuSpec` 接口不变。
|
||||
3. **标定 T_cmd**: 当前取 50ns 估计值,实测后改 `t_cmd_ns` 一处即可。
|
||||
3. **标定 T_cmd**: 当前按 0 处理 (未标定, issue#36; MergeBatch 合并收益已由 move_eff 搬移效率模型刻画, 不依赖 T_cmd 估计值), 实测后改 `t_cmd_ns` 一处即可。
|
||||
4. **新分支**: 在 `branches/` 下加一个文件实现三接口 + 在 `router.py` 注册 + 在 `evaluator._BRANCH_EVAL` 注册;约束一律走 `constraints.py`,不在分支内另造规则。
|
||||
|
||||
@@ -50,7 +50,9 @@ case (B, M, N, K, dtype)
|
||||
│
|
||||
├─ 单 batch M×N 太小, 合并搬移 ──▶ MergeBatch (冗余算力换搬移效率)
|
||||
│ 进入: 5 条件 (L0C/搬移量/tile/算存比/b_core≥2b0)
|
||||
│ 胜出: K 截断 (k_L1=K) 且 b_core > b0(T_comp+T_write)/T_cmd
|
||||
│ 胜出: 命令节省(cmds差×T_cmd) + 搬移效率节省(合并 tile 放大 b0 倍,
|
||||
│ issue#36) > drain 惩罚; K截断且效率打平时退化为
|
||||
│ b_core > b0(T_comp+T_write)/T_cmd (v1.1 §4.5)
|
||||
│
|
||||
└─ 逐 batch 计算 ──────────────▶ IterBatch (无浪费, 最朴素)
|
||||
进入: b_core≥1 + 负载均衡 + L1 四形态之一 + 搬移效率
|
||||
|
||||
@@ -43,7 +43,18 @@ k_L1 被 512B 截断省出的 L1 空间容纳更多 batch,提升 batch 间流
|
||||
|
||||
## 4. 时延模型(v1.1 §4)
|
||||
|
||||
符号:T_load = k_L1(M+N)·dt/BW_pc(每 K 分块搬移)、T_comp = 2MN·k_L1/Q₁₆(每 K 分块计算)、T_write = MN·outB/W_GM(单 batch 写回)、T_cmd(单次 GM→L1 DMA 固定开销,~50ns)。
|
||||
符号:T_load = k_L1(M+N)·dt/(BW_pc·eff)(每 K 分块搬移,eff=move_eff(单命令tile),见下)、T_comp = 2MN·k_L1/Q₁₆(每 K 分块计算)、T_write = MN·outB/W_GM(单 batch 写回)、T_cmd(单次 GM→L1 DMA 固定开销,**默认按 0**——未标定;issue#36 起合并收益由搬移效率模型刻画,不依赖 T_cmd 估计值)。
|
||||
|
||||
> **搬移效率模型 (issue#36, 用户澄清)**: 单命令搬移效率由单块 tile = nValue×dValue×dt
|
||||
> 决定 —— eff(tile) = min(1, tile/min_TileSize),达 16KB 饱和、之下线性退化 (与进入
|
||||
> 条件 4 的效率下限语义同源)。**合并 b0 个 batch 使单块 tile 放大 b0 倍** (A 侧
|
||||
> b0·M·k_L1^m·dt, B 侧 b0·N·k_L1^m·dt; 堆叠方向视转置/排布: A ND 非转置沿 M(nValue)
|
||||
> 堆叠, B ND 非转置沿 N(dValue) 堆叠, 乘积不变), 相对 IterBatch 逐 batch 搬移
|
||||
> (A 侧 tile = M·k_L1^iter·dt) 效率更高 —— **即便 T_cmd=0 也有收益**。
|
||||
> GM→L1 数据时延按两侧字节加权: t_data = (V_A/eff_A + V_B/eff_B)/W_GM;
|
||||
> GM 字节量不变 (仍 = V_in)。效率模型只接入切B 两分支 (逐命令 tile 小、效率差显著);
|
||||
> ASW/StreamK 单命令 tile 通常 ≥ 数百 KB 已饱和 (极端小 tile 形状有"效率降级"标注通道,
|
||||
> issue#34)。
|
||||
|
||||
$$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}}$$
|
||||
|
||||
@@ -72,11 +83,11 @@ c/d 形态切 K 而合并侧每核命令数更少, 则按实际节省判定。
|
||||
|
||||
## 5. MergeBatch vs IterBatch 净收益
|
||||
|
||||
泛化分界 (issue#35, 覆盖三种情形): 直接比较两分支**实际每核 DMA 命令数** ——
|
||||
泛化分界 (issue#35 命令数 / issue#36 搬移效率, 覆盖三种情形): 直接比较两分支**实际每核 DMA 命令数**与**效率加权搬移时延** ——
|
||||
|
||||
$$\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}$$
|
||||
$$\text{净收益} = \underbrace{(cmds_{iter}-cmds_{mb})\,T_{cmd}}_{\text{命令节省}} + \underbrace{(t_{data}^{iter}-t_{data}^{mb})}_{\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_cmd;L1 绑定理想情形命令数打平、净收益恒负。大 B(b_core 大)且小 MN(T_comp 小)时 MergeBatch 最优。T_cmd 的物理成因:Nd2Nz 描述符配置(7 字段写 DMA 寄存器)+ 地址生成 + 突发启动 + L1 同步握手。
|
||||
其中效率节省来自合并 tile 放大 (t_data 按 eff(tile) 加权, 见 §4)。**T_cmd=0 时命令节省为 0, 效率节省依然在项** —— MergeBatch 凭搬移效率胜出 (用户澄清口径)。K 截断且效率打平 (两侧 tile 均 ≥16KB 饱和) 且 T_cmd>0 时严格退化为 v1.1 §4.5 闭式 b_core > b₀(T_comp+T_write)/T_cmd;L1 绑定理想情形 (k_L1^m=k_L1^iter/b₀ 且 tile 均饱和) 命令数与效率均打平、净收益恒负。大 B(b_core 大)且小 MN(T_comp 小、IterBatch 单 batch tile 小未饱和)时 MergeBatch 最优。T_cmd 的物理成因:Nd2Nz 描述符配置(7 字段写 DMA 寄存器)+ 地址生成 + 突发启动 + L1 同步握手 (待 msProf 标定后恢复非零取值)。
|
||||
|
||||
## 6. 与源码的差异(v1.1 §5.1)
|
||||
|
||||
|
||||
@@ -43,11 +43,14 @@ $$T_{iter} = \underbrace{b_{core}\cdot n_K\cdot(T_{load} + T_{cmd})}_{\text{搬
|
||||
> **GM 数据量口径 (issue#31)**: 形态 a/b/c/d 的 K 段/驻留侧数据互不重叠、每个输入字节
|
||||
> 恰好从 GM 读一次 (形态 c 的驻留侧每 batch 只搬一次; 切 K 末段按实际剩余计, 无 padding
|
||||
> 上取) —— **芯片 GM 读取量 = V_in**, 与 L2 容量无关 (IterBatch 无 L2 级重复读)。
|
||||
> n_K 只决定 DMA 命令数 (T_cmd 项) 与双缓冲调度, 不放大数据量; 数据时延按 V_in/W_GM 计。
|
||||
> n_K 只决定 DMA 命令数 (T_cmd 项, 950PR 默认 t_cmd=0) 与双缓冲调度, 不放大数据量;
|
||||
> 数据时延按**效率加权** (V_A/eff_A + V_B/eff_B)/W_GM 计 (issue#36: 单命令 tile =
|
||||
> nValue×dValue×dt 越小有效带宽越低, 达 min_TileSize=16KB 饱和; 分侧口径 —— a/b 形态
|
||||
> 双侧整 K、c 形态驻留侧整 K + 对侧 k_L1 分块、d 形态双侧 k_L1 分块)。
|
||||
|
||||
## 6. 与 MergeBatch 的分界
|
||||
|
||||
见 [01_MergeBatch分支.md](01_MergeBatch分支.md) §4~5。IterBatch 在 **L1 绑定情形恒优**;MergeBatch 仅在 K 截断且 b_core 足够大时胜。
|
||||
见 [01_MergeBatch分支.md](01_MergeBatch分支.md) §4~5。IterBatch 在 **L1 绑定理想情形恒优**;MergeBatch 凭 命令节省 (T_cmd>0 时) 与 **搬移效率节省** (合并 tile 放大 b0 倍, T_cmd=0 时仍成立, issue#36) 胜出 —— 净收益 > 0 即 MergeBatch 优。
|
||||
|
||||
## 7. 与源码的差异(v1.1 §5.2)
|
||||
|
||||
|
||||
@@ -177,6 +177,13 @@ dma_cmd_count 为**单核**命令数 (各核 DMA 引擎并行执行, 墙钟 T_cm
|
||||
| 特殊分支 | K=1: V_in; K=0: 0 | 0 | S_A→L2 写口; else GM (K=0 只有输出) |
|
||||
| 转Matmul | V_in (折叠后) | 0 | S_A→L2; else GM |
|
||||
|
||||
> **搬移效率 (时间列口径, issue#36)**: 上表为**字节量**口径 (不受效率模型影响);
|
||||
> 切B 两分支的 GM→L1 **时间**按单命令 tile 效率加权 t = (V_A/eff_A + V_B/eff_B)/W_GM,
|
||||
> eff = min(1, tile/min_TileSize), tile = nValue×dValue×dt。MergeBatch 合并使 tile
|
||||
> 放大 b0 倍 -> 效率项是 T_cmd=0 时 MergeBatch 的主要收益来源 (详见
|
||||
> docs/02_分支理论/01_MergeBatch分支.md §4~5)。ASW/StreamK 单命令 tile 大、效率
|
||||
> 恒饱和, 不接入 (极端小 tile 形状走 issue#34 "效率降级"标注通道)。
|
||||
|
||||
时延计算: 全核并发时 t = 芯片字节 / 芯片带宽; 降核 (used < C) 时按 used×单核份额
|
||||
(线性假设, issue#26 标注), Cube t = 芯片 flops / (used × q_cube(dtype))。
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
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
|
||||
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
|
||||
to_matmul_demo,1,1,2048,2048,2048,bf16,bf16,bf16,0,0,0,,0
|
||||
special_k0_demo,128,128,256,256,0,bf16,bf16,bf16,0,0,0,,0
|
||||
special_k1_demo,128,128,256,256,1,bf16,bf16,bf16,0,0,0,,0
|
||||
merge_demo_k_trunc,2048,2048,32,32,256,bf16,bf16,bf16,0,0,0,,0
|
||||
merge_demo_k_trunc,2048,2048,16,64,128,bf16,bf16,bf16,0,0,0,,0
|
||||
merge_iter_arbitrate,128,128,64,64,512,bf16,bf16,bf16,0,0,0,,0
|
||||
iter_demo_form_b,128,128,64,64,256,bf16,bf16,bf16,0,0,0,,0
|
||||
iter_demo_form_d,64,64,64,64,8192,bf16,bf16,bf16,0,0,0,,0
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
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"
|
||||
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 核"
|
||||
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乒乓流水)"
|
||||
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)"
|
||||
merge_demo_k_trunc,MergeBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B均分(核间零重复读零依赖),64,4,64,256,128,128,12,合并驻留,64,256,64,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/算存比上限23.7/b_core=64); K截断; 合并后单次DMA搬入 A'[64,128]+B'[128,256]; 输出落点: L2驻留 (整case V_in+V_out=40.0MB vs L2=128MB)"
|
||||
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驻留
|
||||
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驻留
|
||||
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"
|
||||
|
||||
|
@@ -2,27 +2,27 @@
|
||||
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_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,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 直写与读竞争"
|
||||
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 直写与读竞争"
|
||||
merge_demo_k_trunc,2048,2048,16,64,128,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,64,256,128,128,12,合并驻留,64,256,64,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/算存比上限23.7/b_core=64); K截断; 合并后单次DMA搬入 A'[64,128]+B'[128,256]; 输出落点: L2驻留 (整case V_in+V_out=40.0MB vs L2=128MB)",41943040,0.0,2.62144e-05,0.0,2.62144e-05,16,0.0,2147483648.0,4.418690633744856e-06,4194304,8.065969230769231e-07,0.0,2.62144e-05,1.1945434884457107e-07,2.6333854348844573e-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.048576e-05,4,0.0,536870912.0,1.104672658436214e-06,1048576,2.0164923076923077e-07,0.0,1.048576e-05,3.265804723013612e-07,1.081234047230136e-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.24288e-06,4,0.0,268435456.0,5.52336329218107e-07,1048576,2.0164923076923077e-07,0.0,5.24288e-06,1.8849638999683443e-07,5.431376389996834e-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.388608e-05,16,0.0,4294967296.0,8.837381267489712e-06,524288,3.2768e-07,0.0,8.421376e-05,7.16176329218107e-07,8.492993632921811e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
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重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
asw_demo_full,2,2,8192,8192,1024,bf16,bf16,bf16,False,False,False,True,0,asw_demo_full,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,16,16,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,1024,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,16,True,2,"tile枚举: P=16, 有界枚举最优 mCnt=16 x nCnt=16 (tile 512x512, 每batch搬入512.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=64.0MB, V_out=256.0MB, L2=128MB); 尾轮: r=0 无尾轮",67108864,1006632960,4.194304e-05,0.00019358326153846154,0.00023552630153846153,0.0,0.0,274877906944.0,0.0005655924011193416,268435456,0.00016777216,0.0,0.0005655924011193416,0.0,0.0005655924011193416,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
asw_demo_reduce_core,16,16,256,256,128,bf16,bf16,bf16,False,False,False,True,0,asw_demo_reduce_core,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,16,1,1,1,1,"降核: 只用16核, 每核一个L0C满载输出块, 其余核闲置",0,1,256,256,128,128,1,标准核内流水,256,256,64,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=16.00<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",2097152,0,2.62144e-06,0.0,2.62144e-06,0.0,0.0,268435456.0,1.104672658436214e-06,2097152,8.065969230769231e-07,0.0,2.62144e-06,0.0,2.62144e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b4_m1_n128_k256,4,4,1,128,256,bf16,bf16,bf16,False,False,False,True,0,b4_m1_n128_k256,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,1,1,1,1,1,"降核: 只用1核, 每核一个L0C满载输出块, 其余核闲置",0,1,1,128,256,256,1,标准核内流水,1,128,128,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=0.01<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",264192,0,5.28384e-06,0.0,5.28384e-06,0.0,0.0,262144.0,1.7260510288065844e-08,1024,6.3015384615384615e-09,0.0,5.28384e-06,0.0,5.28384e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b8_m2_n192_k128,8,8,2,192,128,bf16,bf16,bf16,False,False,False,True,0,b8_m2_n192_k128,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,1,1,1,1,1,"降核: 只用1核, 每核一个L0C满载输出块, 其余核闲置",0,1,2,192,128,128,1,标准核内流水,2,192,80,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=0.05<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",397312,0,7.94624e-06,0.0,7.94624e-06,0.0,0.0,786432.0,5.178153086419753e-08,6144,3.7809230769230766e-08,0.0,7.94624e-06,0.0,7.94624e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b16_m4_n256_k192,16,16,4,256,192,bf16,bf16,bf16,False,False,False,True,0,b16_m4_n256_k192,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,1,1,1,1,1,"降核: 只用1核, 每核一个L0C满载输出块, 其余核闲置",0,1,4,256,192,192,1,标准核内流水,4,256,64,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=0.25<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",1597440,0,3.19488e-05,0.0,3.19488e-05,0.0,0.0,6291456.0,4.1425224691358024e-07,32768,2.0164923076923077e-07,0.0,3.19488e-05,0.0,3.19488e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b32_m8_n128_k256,32,32,8,128,256,bf16,bf16,bf16,False,False,False,True,0,b32_m8_n128_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,8,128,256,256,1,a_单batch全驻留,8,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,单batch全驻留: (MK+KN)*dtype=68KB <= L1; 输出落点: L2驻留,2228224,0.0,1.39264e-06,0.0,1.44264e-06,1,5.0000000000000004e-08,16777216.0,3.452102057613169e-08,65536,1.2603076923076923e-08,0.0,1.44264e-06,4.712409749920861e-08,1.4897640974992086e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b64_m16_n256_k512,64,64,16,256,512,bf16,bf16,bf16,False,False,False,True,0,b64_m16_n256_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,16,256,512,240,1,c_一侧驻留+对侧切K,16,256,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"一侧驻留(A)+对侧切K: A驻留16KB, 预算L1/2, k_L1=240, dValueA=480B/dValueB=512B; 输出落点: L2驻留",17825792,0.0,1.114112e-05,0.0,1.1441120000000001e-05,6,3.0000000000000004e-07,268435456.0,5.52336329218107e-07,524288,1.0082461538461538e-07,0.0,1.1441120000000001e-05,1.798661348528015e-07,1.1620986134852803e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b128_m8_n192_k256,128,128,8,192,256,bf16,bf16,bf16,False,False,False,True,0,b128_m8_n192_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,8,192,256,256,2,b_双batch乒乓,8,192,80,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=200KB <= L1; 输出落点: L2驻留,13107200,0.0,8.192e-06,0.0,8.392e-06,4,2.0000000000000002e-07,100663296.0,2.0712612345679012e-07,393216,7.561846153846153e-08,0.0,8.392e-06,7.068614624881291e-08,8.462686146248813e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b32_m8_n128_k256,32,32,8,128,256,bf16,bf16,bf16,False,False,False,True,0,b32_m8_n128_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,8,128,256,256,1,a_单batch全驻留,8,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,单batch全驻留: (MK+KN)*dtype=68KB <= L1; 输出落点: L2驻留,2228224,0.0,1.6384e-06,0.0,1.6384e-06,1,0.0,16777216.0,3.452102057613169e-08,65536,1.2603076923076923e-08,0.0,1.6384e-06,4.712409749920861e-08,1.6855240974992087e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b64_m16_n256_k512,64,64,16,256,512,bf16,bf16,bf16,False,False,False,True,0,b64_m16_n256_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,16,256,512,240,1,c_一侧驻留+对侧切K,16,256,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"一侧驻留(A)+对侧切K: A驻留16KB, 预算L1/2, k_L1=240, dValueA=480B/dValueB=512B; 输出落点: L2驻留",17825792,0.0,1.114112e-05,0.0,1.114112e-05,6,0.0,268435456.0,5.52336329218107e-07,524288,1.0082461538461538e-07,0.0,1.114112e-05,1.798661348528015e-07,1.1320986134852803e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b128_m8_n192_k256,128,128,8,192,256,bf16,bf16,bf16,False,False,False,True,0,b128_m8_n192_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,8,192,256,256,2,b_双batch乒乓,8,192,80,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=200KB <= L1; 输出落点: L2驻留,13107200,0.0,9.17504e-06,0.0,9.17504e-06,4,0.0,100663296.0,2.0712612345679012e-07,393216,7.561846153846153e-08,0.0,9.17504e-06,7.068614624881291e-08,9.245726146248813e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b32_m16_n8192_k7168,32,32,16,8192,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m16_n8192_k7168,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,1,8,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,16,1024,7168,112,1,双缓冲驻留当前tile输入,16,1024,16,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,8,True,2,"tile枚举: 效率降级(放开约束4, dValue 按 128B 硬下限, 搬移效率低于模型假设, 时延可能低估): P=1, mCnt=1 x nCnt=8 (tile 16x1024, 每batch搬入113.8MB, r=0); Base tile 16x1024 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=3591.0MB, V_out=8.0MB, L2=128MB); 尾轮: r=0 无尾轮",3765436416,51380224,0.00235339776,9.880812307692307e-06,0.0023632785723076925,0.0,0.0,60129542144.0,0.00012372333774485596,8388608,5.24288e-06,0.0,0.0023685214523076923,0.0,0.0023685214523076923,MTE2,True,,访存Bound(GM读写共享+L2重复读),"效率降级标注 (plan.note): 搬移效率下限不满足 —— 方案照常给出 (兜底), 但实际效率低于模型假设, 时延可能低估; 建议调整 dtype/布局 | 瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b4_m1_n8192_k8192,4,4,1,8192,8192,bf16,bf16,bf16,False,False,False,True,0,b4_m1_n8192_k8192,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,1,8192,256,256,1,K段标准分块流水,1,128,64,allocate(部分和驻留L2),"resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换)",0,4194304,grid_K=32路切K+归约,1,1,32,0,0,0,0,True,4,"P=0.50, grid_K=32, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终",536936448,0.0,0.00033558528,0.0,0.00033558528,0.0,0.0,536870912.0,1.104672658436214e-06,0.0,0.0,1.731729603729604e-06,0.00033558528,1.731729603729604e-06,0.0003373170096037296,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b16_m2_n4096_k7168,16,16,2,4096,7168,bf16,bf16,bf16,False,False,False,True,0,b16_m2_n4096_k7168,StreamK,Ascend950PR,batch_mat_mul_v3,32,1,1,1,16,"B/M/N切出16块, 每块16核切K归约 (归约组内核c负责K段[c*K/16,(c+1)*K/16))",1,1,2,4096,448,256,1,K段标准分块流水,2,128,64,allocate(部分和驻留L2),"resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换)",0,8388608,grid_K=16路切K+归约,1,1,16,0,0,0,0,True,4,"P=2.00, grid_K=16, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终",939982848,0,0.00058748928,0.0,0.00058748928,0.0,0.0,1879048192.0,3.866354304526749e-06,0.0,0.0,1.7726896037296038e-06,0.00058748928,1.7726896037296038e-06,0.0005892619696037297,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b32_m64_n64_k7168,32,32,64,64,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m64_n64_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,64,64,7168,1024,1,d_两侧都切K,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,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: L2驻留",58720256,0.0,3.670016e-05,0.0,3.7050160000000004e-05,7,3.5000000000000004e-07,1879048192.0,3.866354304526749e-06,262144,5.041230769230769e-08,0.0,3.7050160000000004e-05,6.027486369104147e-07,3.765290863691042e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b64_m1024_n1024_k7168,64,64,1024,1024,7168,bf16,bf16,bf16,False,False,False,True,0,b64_m1024_n1024_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,1024,1024,7168,64,1,d_两侧都切K,176,176,64,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=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: 直写GM",1879048192,0.0,0.00117440512,0.0,0.0011856051200000001,224,1.1200000000000001e-05,962072674304.0,0.0019795734039176954,134217728,8.388608e-05,0.0,0.0019795734039176954,5.078042126748971e-05,0.0020303538251851853,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b32_m64_n64_k7168,32,32,64,64,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m64_n64_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,64,64,7168,1024,1,d_两侧都切K,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,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: L2驻留",58720256,0.0,3.670016e-05,0.0,3.670016e-05,7,0.0,1879048192.0,3.866354304526749e-06,262144,5.041230769230769e-08,0.0,3.670016e-05,6.027486369104147e-07,3.730290863691042e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"瓶颈在 MTE2 搬移链 (GM 读写共享总线 + L2 重复读): 可增大 tile 提升 dValue/单核搬移量、利用 L2 驻留吸收重复读 (ASW swizzle/分组方向), 或评估输出驻留 L2 以减少 GM 直写与读竞争"
|
||||
b64_m1024_n1024_k7168,64,64,1024,1024,7168,bf16,bf16,bf16,False,False,False,True,0,b64_m1024_n1024_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,1024,1024,7168,64,1,d_两侧都切K,176,176,64,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=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: 直写GM",1879048192,0.0,0.00117440512,0.0,0.00117440512,224,0.0,962072674304.0,0.0019795734039176954,134217728,8.388608e-05,0.0,0.0019795734039176954,5.078042126748971e-05,0.0020303538251851853,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b128_m2048_n2048_k1536,128,128,2048,2048,1536,bf16,bf16,bf16,False,False,False,True,0,b128_m2048_n2048_k1536,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,4,4,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,1536,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,64,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=4 x nCnt=4 (tile 512x512, 每batch搬入48.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=1536.0MB, V_out=1024.0MB, L2=128MB); 尾轮: r=0 无尾轮",1610612736,4831838208,0.00100663296,0.0009291996553846154,0.0019358326153846154,0.0,0.0,1649267441664.0,0.0033935544067160493,1073741824,0.00067108864,0.0,0.0033935544067160493,0.0,0.0033935544067160493,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b64_m1024_n8192_k2048,64,64,1024,8192,2048,bf16,bf16,bf16,False,False,False,True,0,b64_m1024_n8192_k2048,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,2,16,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,2048,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,64,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=2 x nCnt=16 (tile 512x512, 每batch搬入128.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=2304.0MB, V_out=1024.0MB, L2=128MB); 尾轮: r=0 无尾轮",2415919104,6174015488,0.00150994944,0.0011873106707692308,0.0026972601107692305,0.0,0.0,2199023255552.0,0.004524739208954733,1073741824,0.00067108864,0.0,0.004524739208954733,0.0,0.004524739208954733,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b32_m1024_n1024_k512,32,32,1024,1024,512,bf16,bf16,bf16,False,False,False,True,0,b32_m1024_n1024_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,1024,1024,512,64,1,d_两侧都切K,176,176,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: L2驻留",67108864,0.0,4.194304e-05,0.0,4.234304e-05,8,4.0000000000000003e-07,34359738368.0,7.06990501399177e-05,67108864,1.290555076923077e-05,0.0,7.06990501399177e-05,2.1742932036720483e-05,9.244198217663819e-05,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b32_m1024_n1024_k512,32,32,1024,1024,512,bf16,bf16,bf16,False,False,False,True,0,b32_m1024_n1024_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,1024,1024,512,64,1,d_两侧都切K,176,176,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: L2驻留",67108864,0.0,4.194304e-05,0.0,4.194304e-05,8,0.0,34359738368.0,7.06990501399177e-05,67108864,1.290555076923077e-05,0.0,7.06990501399177e-05,2.1742932036720483e-05,9.244198217663819e-05,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b128_m4096_n4096_k8192,128,128,4096,4096,8192,bf16,bf16,bf16,False,False,False,True,0,b128_m4096_n4096_k8192,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,8,8,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,8192,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,256,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=8 x nCnt=8 (tile 512x512, 每batch搬入1024.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=16384.0MB, V_out=4096.0MB, L2=128MB); 尾轮: r=0 无尾轮",17179869184,120259084288,0.01073741824,0.023126746978461538,0.033864165218461535,0.0,0.0,35184372088832.0,0.07239582734327572,4294967296,0.00268435456,0.0,0.07239582734327572,0.0,0.07239582734327572,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b32_m8192_n4096_k7168,32,32,8192,4096,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m8192_n4096_k7168,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,16,8,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,7168,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,128,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=16 x nCnt=8 (tile 512x512, 每batch搬入1792.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=5376.0MB, V_out=2048.0MB, L2=128MB); 尾轮: r=0 无尾轮",5637144576,54492397568,0.00352321536,0.010479307224615384,0.014002522584615384,0.0,0.0,15393162788864.0,0.031673174462683126,2147483648,0.00134217728,0.0,0.031673174462683126,0.0,0.031673174462683126,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
b32_m2048_n2048_k8192,32,32,2048,2048,8192,bf16,bf16,bf16,False,False,False,True,0,b32_m2048_n2048_k8192,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,4,4,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,8192,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,16,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=4 x nCnt=4 (tile 512x512, 每batch搬入256.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=2048.0MB, V_out=256.0MB, L2=128MB); 尾轮: r=0 无尾轮",2147483648,6442450944,0.00134217728,0.0012389328738461537,0.002581110153846154,0.0,0.0,2199023255552.0,0.004524739208954733,268435456,0.00016777216,0.0,0.004524739208954733,0.0,0.004524739208954733,MMAD,True,,计算Bound,"瓶颈在 Cube 计算: 已接近理论算力上限, 检查是否有冗余计算 (MergeBatch 交叉项) 可消除"
|
||||
|
||||
|
@@ -2,27 +2,27 @@
|
||||
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_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,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 (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_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 条件满足
|
||||
merge_demo_k_trunc,2048,2048,16,64,128,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,64,256,128,128,12,合并驻留,64,256,64,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/算存比上限23.7/b_core=64); K截断; 合并后单次DMA搬入 A'[64,128]+B'[128,256]; 输出落点: L2驻留 (整case V_in+V_out=40.0MB vs L2=128MB)",41943040,0.0,2.62144e-05,0.0,2.62144e-05,16,0.0,2147483648.0,4.418690633744856e-06,4194304,8.065969230769231e-07,0.0,2.62144e-05,1.1945434884457107e-07,2.6333854348844573e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"两分支均合法, 仲裁: [分界条件] MergeBatch最优=True (K截断(k_l1^m=128>=K); 每核命令数 MergeBatch=16 vs IterBatch=64 (命令节省=0.00us) + 搬移效率节省=15.73us vs drain惩罚=(b0-1)*(T_comp+T_write)=0.17us -> MergeBatch优); [时延模型] T_MergeBatch=26.33us vs T_IterBatch=41.97us -> 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.048576e-05,4,0.0,536870912.0,1.104672658436214e-06,1048576,2.0164923076923077e-07,0.0,1.048576e-05,3.265804723013612e-07,1.081234047230136e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),"两分支均合法, 仲裁: [分界条件] MergeBatch最优=False (L1绑定(k_l1^m=256<K=512); 每核命令数 MergeBatch=4 vs IterBatch=4 (命令节省=0.00us) + 搬移效率节省=0.00us vs drain惩罚=(b0-1)*(T_comp+T_write)=0.44us -> IterBatch优); [时延模型] T_MergeBatch=10.86us vs T_IterBatch=10.81us -> 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.24288e-06,4,0.0,268435456.0,5.52336329218107e-07,1048576,2.0164923076923077e-07,0.0,5.24288e-06,1.8849638999683443e-07,5.431376389996834e-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.388608e-05,16,0.0,4294967296.0,8.837381267489712e-06,524288,3.2768e-07,0.0,8.421376e-05,7.16176329218107e-07,8.492993632921811e-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)"
|
||||
asw_demo_full,2,2,8192,8192,1024,bf16,bf16,bf16,False,False,False,True,0,asw_demo_full,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,16,16,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,1024,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,16,True,2,"tile枚举: P=16, 有界枚举最优 mCnt=16 x nCnt=16 (tile 512x512, 每batch搬入512.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=64.0MB, V_out=256.0MB, L2=128MB); 尾轮: r=0 无尾轮",67108864,1006632960,4.194304e-05,0.00019358326153846154,0.00023552630153846153,0.0,0.0,274877906944.0,0.0005655924011193416,268435456,0.00016777216,0.0,0.0005655924011193416,0.0,0.0005655924011193416,MMAD,True,,计算Bound,ASW_Basic兜底 (StreamK未过: 1_并行缺口: P=B*MN*4B/L0C <= C/2; 2_单核K段下限: K/grid_K >= 256B/dtype 且 grid_K>=2; 3_归约代价可接受)
|
||||
asw_demo_reduce_core,16,16,256,256,128,bf16,bf16,bf16,False,False,False,True,0,asw_demo_reduce_core,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,16,1,1,1,1,"降核: 只用16核, 每核一个L0C满载输出块, 其余核闲置",0,1,256,256,128,128,1,标准核内流水,256,256,64,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=16.00<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",2097152,0,2.62144e-06,0.0,2.62144e-06,0.0,0.0,268435456.0,1.104672658436214e-06,2097152,8.065969230769231e-07,0.0,2.62144e-06,0.0,2.62144e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),ASW_Basic兜底 (StreamK未过: 2_单核K段下限: K/grid_K >= 256B/dtype 且 grid_K>=2)
|
||||
b4_m1_n128_k256,4,4,1,128,256,bf16,bf16,bf16,False,False,False,True,0,b4_m1_n128_k256,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,1,1,1,1,1,"降核: 只用1核, 每核一个L0C满载输出块, 其余核闲置",0,1,1,128,256,256,1,标准核内流水,1,128,128,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=0.01<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",264192,0,5.28384e-06,0.0,5.28384e-06,0.0,0.0,262144.0,1.7260510288065844e-08,1024,6.3015384615384615e-09,0.0,5.28384e-06,0.0,5.28384e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),ASW_Basic兜底 (StreamK未过: 2_单核K段下限: K/grid_K >= 256B/dtype 且 grid_K>=2; 3_归约代价可接受: K > grid_K^2/(grid_K-1)*theta_c)
|
||||
b8_m2_n192_k128,8,8,2,192,128,bf16,bf16,bf16,False,False,False,True,0,b8_m2_n192_k128,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,1,1,1,1,1,"降核: 只用1核, 每核一个L0C满载输出块, 其余核闲置",0,1,2,192,128,128,1,标准核内流水,2,192,80,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=0.05<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",397312,0,7.94624e-06,0.0,7.94624e-06,0.0,0.0,786432.0,5.178153086419753e-08,6144,3.7809230769230766e-08,0.0,7.94624e-06,0.0,7.94624e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),ASW_Basic兜底 (StreamK未过: 2_单核K段下限: K/grid_K >= 256B/dtype 且 grid_K>=2; 3_归约代价可接受: K > grid_K^2/(grid_K-1)*theta_c)
|
||||
b16_m4_n256_k192,16,16,4,256,192,bf16,bf16,bf16,False,False,False,True,0,b16_m4_n256_k192,ASW_Basic_降核,Ascend950PR,batch_mat_mul_v3,1,1,1,1,1,"降核: 只用1核, 每核一个L0C满载输出块, 其余核闲置",0,1,4,256,192,192,1,标准核内流水,4,256,64,allocate,resident(整case全驻留S_A),0,0,不涉及(每核一块无尾轮),1,1,1,0,0,0,0,True,2,"P=0.25<C, 降核是理性选择 (强切则 tile 跌破搬移效率下限反而更慢)",1597440,0,3.19488e-05,0.0,3.19488e-05,0.0,0.0,6291456.0,4.1425224691358024e-07,32768,2.0164923076923077e-07,0.0,3.19488e-05,0.0,3.19488e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),ASW_Basic兜底 (StreamK未过: 2_单核K段下限: K/grid_K >= 256B/dtype 且 grid_K>=2; 3_归约代价可接受: K > grid_K^2/(grid_K-1)*theta_c)
|
||||
b32_m8_n128_k256,32,32,8,128,256,bf16,bf16,bf16,False,False,False,True,0,b32_m8_n128_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,8,128,256,256,1,a_单batch全驻留,8,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,单batch全驻留: (MK+KN)*dtype=68KB <= L1; 输出落点: L2驻留,2228224,0.0,1.39264e-06,0.0,1.44264e-06,1,5.0000000000000004e-08,16777216.0,3.452102057613169e-08,65536,1.2603076923076923e-08,0.0,1.44264e-06,4.712409749920861e-08,1.4897640974992086e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b64_m16_n256_k512,64,64,16,256,512,bf16,bf16,bf16,False,False,False,True,0,b64_m16_n256_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,16,256,512,240,1,c_一侧驻留+对侧切K,16,256,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"一侧驻留(A)+对侧切K: A驻留16KB, 预算L1/2, k_L1=240, dValueA=480B/dValueB=512B; 输出落点: L2驻留",17825792,0.0,1.114112e-05,0.0,1.1441120000000001e-05,6,3.0000000000000004e-07,268435456.0,5.52336329218107e-07,524288,1.0082461538461538e-07,0.0,1.1441120000000001e-05,1.798661348528015e-07,1.1620986134852803e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b128_m8_n192_k256,128,128,8,192,256,bf16,bf16,bf16,False,False,False,True,0,b128_m8_n192_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,8,192,256,256,2,b_双batch乒乓,8,192,80,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=200KB <= L1; 输出落点: L2驻留,13107200,0.0,8.192e-06,0.0,8.392e-06,4,2.0000000000000002e-07,100663296.0,2.0712612345679012e-07,393216,7.561846153846153e-08,0.0,8.392e-06,7.068614624881291e-08,8.462686146248813e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b32_m8_n128_k256,32,32,8,128,256,bf16,bf16,bf16,False,False,False,True,0,b32_m8_n128_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,8,128,256,256,1,a_单batch全驻留,8,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,单batch全驻留: (MK+KN)*dtype=68KB <= L1; 输出落点: L2驻留,2228224,0.0,1.6384e-06,0.0,1.6384e-06,1,0.0,16777216.0,3.452102057613169e-08,65536,1.2603076923076923e-08,0.0,1.6384e-06,4.712409749920861e-08,1.6855240974992087e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b64_m16_n256_k512,64,64,16,256,512,bf16,bf16,bf16,False,False,False,True,0,b64_m16_n256_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,16,256,512,240,1,c_一侧驻留+对侧切K,16,256,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"一侧驻留(A)+对侧切K: A驻留16KB, 预算L1/2, k_L1=240, dValueA=480B/dValueB=512B; 输出落点: L2驻留",17825792,0.0,1.114112e-05,0.0,1.114112e-05,6,0.0,268435456.0,5.52336329218107e-07,524288,1.0082461538461538e-07,0.0,1.114112e-05,1.798661348528015e-07,1.1320986134852803e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b128_m8_n192_k256,128,128,8,192,256,bf16,bf16,bf16,False,False,False,True,0,b128_m8_n192_k256,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),4,1,8,192,256,256,2,b_双batch乒乓,8,192,80,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=200KB <= L1; 输出落点: L2驻留,13107200,0.0,9.17504e-06,0.0,9.17504e-06,4,0.0,100663296.0,2.0712612345679012e-07,393216,7.561846153846153e-08,0.0,9.17504e-06,7.068614624881291e-08,9.245726146248813e-06,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b32_m16_n8192_k7168,32,32,16,8192,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m16_n8192_k7168,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,1,8,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,16,1024,7168,112,1,双缓冲驻留当前tile输入,16,1024,16,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,8,True,2,"tile枚举: 效率降级(放开约束4, dValue 按 128B 硬下限, 搬移效率低于模型假设, 时延可能低估): P=1, mCnt=1 x nCnt=8 (tile 16x1024, 每batch搬入113.8MB, r=0); Base tile 16x1024 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=3591.0MB, V_out=8.0MB, L2=128MB); 尾轮: r=0 无尾轮",3765436416,51380224,0.00235339776,9.880812307692307e-06,0.0023632785723076925,0.0,0.0,60129542144.0,0.00012372333774485596,8388608,5.24288e-06,0.0,0.0023685214523076923,0.0,0.0023685214523076923,MTE2,True,,访存Bound(GM读写共享+L2重复读),"IterBatch/MergeBatch 进入条件均不满足, 回落 ASW_Basic; IterBatch未过: 3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读); MergeBatch未过: 1_batch关系与每核份额: BatchA==BatchB 且 b_core=B/C>=2*b0; 2_L0C容量: 2*(b0*M)*(b0*N)*4B <= L0C; 2b_L0AB容量: 合并后 b0*M/b0*N 在最小K粒度下可驻留 L0A/L0B [效率降级标注: 搬移效率低于模型假设, 时延可能低估, 见 plan.note]"
|
||||
b4_m1_n8192_k8192,4,4,1,8192,8192,bf16,bf16,bf16,False,False,False,True,0,b4_m1_n8192_k8192,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,1,8192,256,256,1,K段标准分块流水,1,128,64,allocate(部分和驻留L2),"resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换)",0,4194304,grid_K=32路切K+归约,1,1,32,0,0,0,0,True,4,"P=0.50, grid_K=32, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终",536936448,0.0,0.00033558528,0.0,0.00033558528,0.0,0.0,536870912.0,1.104672658436214e-06,0.0,0.0,1.731729603729604e-06,0.00033558528,1.731729603729604e-06,0.0003373170096037296,MTE2,True,,访存Bound(GM读写共享+L2重复读),"P<=C/2, B/M/N并行度买不满, 切K (grid_K=32)"
|
||||
b16_m2_n4096_k7168,16,16,2,4096,7168,bf16,bf16,bf16,False,False,False,True,0,b16_m2_n4096_k7168,StreamK,Ascend950PR,batch_mat_mul_v3,32,1,1,1,16,"B/M/N切出16块, 每块16核切K归约 (归约组内核c负责K段[c*K/16,(c+1)*K/16))",1,1,2,4096,448,256,1,K段标准分块流水,2,128,64,allocate(部分和驻留L2),"resident(部分和4B驻留L2, 防精度丢失不随C的fp16/fp8转换)",0,8388608,grid_K=16路切K+归约,1,1,16,0,0,0,0,True,4,"P=2.00, grid_K=16, 部分和驻留L2按4B写出, AIV归约后按C dtype=2B写最终",939982848,0,0.00058748928,0.0,0.00058748928,0.0,0.0,1879048192.0,3.866354304526749e-06,0.0,0.0,1.7726896037296038e-06,0.00058748928,1.7726896037296038e-06,0.0005892619696037297,MTE2,True,,访存Bound(GM读写共享+L2重复读),"P<=C/2, B/M/N并行度买不满, 切K (grid_K=16)"
|
||||
b32_m64_n64_k7168,32,32,64,64,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m64_n64_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,64,64,7168,1024,1,d_两侧都切K,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,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: L2驻留",58720256,0.0,3.670016e-05,0.0,3.7050160000000004e-05,7,3.5000000000000004e-07,1879048192.0,3.866354304526749e-06,262144,5.041230769230769e-08,0.0,3.7050160000000004e-05,6.027486369104147e-07,3.765290863691042e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b64_m1024_n1024_k7168,64,64,1024,1024,7168,bf16,bf16,bf16,False,False,False,True,0,b64_m1024_n1024_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,1024,1024,7168,64,1,d_两侧都切K,176,176,64,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=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: 直写GM",1879048192,0.0,0.00117440512,0.0,0.0011856051200000001,224,1.1200000000000001e-05,962072674304.0,0.0019795734039176954,134217728,8.388608e-05,0.0,0.0019795734039176954,5.078042126748971e-05,0.0020303538251851853,MMAD,True,,计算Bound,仅 IterBatch 条件满足
|
||||
b32_m64_n64_k7168,32,32,64,64,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m64_n64_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,64,64,7168,1024,1,d_两侧都切K,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,"两侧都切K: k_L1=1024, K段成对流水, batch边界天然无缝; dValueA=2048B/dValueB=128B; 输出落点: L2驻留",58720256,0.0,3.670016e-05,0.0,3.670016e-05,7,0.0,1879048192.0,3.866354304526749e-06,262144,5.041230769230769e-08,0.0,3.670016e-05,6.027486369104147e-07,3.730290863691042e-05,MTE2,True,,访存Bound(GM读写共享+L2重复读),仅 IterBatch 条件满足
|
||||
b64_m1024_n1024_k7168,64,64,1024,1024,7168,bf16,bf16,bf16,False,False,False,True,0,b64_m1024_n1024_k7168,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),2,1,1024,1024,7168,64,1,d_两侧都切K,176,176,64,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=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: 直写GM",1879048192,0.0,0.00117440512,0.0,0.00117440512,224,0.0,962072674304.0,0.0019795734039176954,134217728,8.388608e-05,0.0,0.0019795734039176954,5.078042126748971e-05,0.0020303538251851853,MMAD,True,,计算Bound,仅 IterBatch 条件满足
|
||||
b128_m2048_n2048_k1536,128,128,2048,2048,1536,bf16,bf16,bf16,False,False,False,True,0,b128_m2048_n2048_k1536,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,4,4,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,1536,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,64,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=4 x nCnt=4 (tile 512x512, 每batch搬入48.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=1536.0MB, V_out=1024.0MB, L2=128MB); 尾轮: r=0 无尾轮",1610612736,4831838208,0.00100663296,0.0009291996553846154,0.0019358326153846154,0.0,0.0,1649267441664.0,0.0033935544067160493,1073741824,0.00067108864,0.0,0.0033935544067160493,0.0,0.0033935544067160493,MMAD,True,,计算Bound,"IterBatch/MergeBatch 进入条件均不满足, 回落 ASW_Basic; IterBatch未过: 3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读); MergeBatch未过: 2_L0C容量: 2*(b0*M)*(b0*N)*4B <= L0C; 2b_L0AB容量: 合并后 b0*M/b0*N 在最小K粒度下可驻留 L0A/L0B; 5_访存Bound: 2MN/(M+N) < R16/b0"
|
||||
b64_m1024_n8192_k2048,64,64,1024,8192,2048,bf16,bf16,bf16,False,False,False,True,0,b64_m1024_n8192_k2048,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,2,16,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,2048,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,64,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=2 x nCnt=16 (tile 512x512, 每batch搬入128.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=2304.0MB, V_out=1024.0MB, L2=128MB); 尾轮: r=0 无尾轮",2415919104,6174015488,0.00150994944,0.0011873106707692308,0.0026972601107692305,0.0,0.0,2199023255552.0,0.004524739208954733,1073741824,0.00067108864,0.0,0.004524739208954733,0.0,0.004524739208954733,MMAD,True,,计算Bound,"IterBatch/MergeBatch 进入条件均不满足, 回落 ASW_Basic; IterBatch未过: 3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读); MergeBatch未过: 1_batch关系与每核份额: BatchA==BatchB 且 b_core=B/C>=2*b0; 2_L0C容量: 2*(b0*M)*(b0*N)*4B <= L0C; 2b_L0AB容量: 合并后 b0*M/b0*N 在最小K粒度下可驻留 L0A/L0B; 5_访存Bound: 2MN/(M+N) < R16/b0"
|
||||
b32_m1024_n1024_k512,32,32,1024,1024,512,bf16,bf16,bf16,False,False,False,True,0,b32_m1024_n1024_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,1024,1024,512,64,1,d_两侧都切K,176,176,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: L2驻留",67108864,0.0,4.194304e-05,0.0,4.234304e-05,8,4.0000000000000003e-07,34359738368.0,7.06990501399177e-05,67108864,1.290555076923077e-05,0.0,7.06990501399177e-05,2.1742932036720483e-05,9.244198217663819e-05,MMAD,True,,计算Bound,仅 IterBatch 条件满足
|
||||
b32_m1024_n1024_k512,32,32,1024,1024,512,bf16,bf16,bf16,False,False,False,True,0,b32_m1024_n1024_k512,IterBatch,Ascend950PR,batch_mat_mul_v3,32,32,1,1,1,切B轮转分配(核间零重复读零依赖),1,1,1024,1024,512,64,1,d_两侧都切K,176,176,64,allocate(GM->L1随路驻留L2),"resident(整case输入+输出<=L2: 输出驻留L2异步回写, GM写=0)",0,0,不涉及(核内不切M/N),1,1,1,0,0,0,0,True,2,"两侧都切K: k_L1=64, K段成对流水, batch边界天然无缝; dValueA=128B/dValueB=2048B; 输出落点: L2驻留",67108864,0.0,4.194304e-05,0.0,4.194304e-05,8,0.0,34359738368.0,7.06990501399177e-05,67108864,1.290555076923077e-05,0.0,7.06990501399177e-05,2.1742932036720483e-05,9.244198217663819e-05,MMAD,True,,计算Bound,仅 IterBatch 条件满足
|
||||
b128_m4096_n4096_k8192,128,128,4096,4096,8192,bf16,bf16,bf16,False,False,False,True,0,b128_m4096_n4096_k8192,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,8,8,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,8192,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,256,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=8 x nCnt=8 (tile 512x512, 每batch搬入1024.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=16384.0MB, V_out=4096.0MB, L2=128MB); 尾轮: r=0 无尾轮",17179869184,120259084288,0.01073741824,0.023126746978461538,0.033864165218461535,0.0,0.0,35184372088832.0,0.07239582734327572,4294967296,0.00268435456,0.0,0.07239582734327572,0.0,0.07239582734327572,MMAD,True,,计算Bound,"IterBatch/MergeBatch 进入条件均不满足, 回落 ASW_Basic; IterBatch未过: 3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读); MergeBatch未过: 2_L0C容量: 2*(b0*M)*(b0*N)*4B <= L0C; 2b_L0AB容量: 合并后 b0*M/b0*N 在最小K粒度下可驻留 L0A/L0B; 5_访存Bound: 2MN/(M+N) < R16/b0"
|
||||
b32_m8192_n4096_k7168,32,32,8192,4096,7168,bf16,bf16,bf16,False,False,False,True,0,b32_m8192_n4096_k7168,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,16,8,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,7168,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,128,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=16 x nCnt=8 (tile 512x512, 每batch搬入1792.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=5376.0MB, V_out=2048.0MB, L2=128MB); 尾轮: r=0 无尾轮",5637144576,54492397568,0.00352321536,0.010479307224615384,0.014002522584615384,0.0,0.0,15393162788864.0,0.031673174462683126,2147483648,0.00134217728,0.0,0.031673174462683126,0.0,0.031673174462683126,MMAD,True,,计算Bound,"IterBatch/MergeBatch 进入条件均不满足, 回落 ASW_Basic; IterBatch未过: 3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读); MergeBatch未过: 1_batch关系与每核份额: BatchA==BatchB 且 b_core=B/C>=2*b0; 2_L0C容量: 2*(b0*M)*(b0*N)*4B <= L0C; 2b_L0AB容量: 合并后 b0*M/b0*N 在最小K粒度下可驻留 L0A/L0B; 5_访存Bound: 2MN/(M+N) < R16/b0"
|
||||
b32_m2048_n2048_k8192,32,32,2048,2048,8192,bf16,bf16,bf16,False,False,False,True,0,b32_m2048_n2048_k8192,ASW_Basic,Ascend950PR,batch_mat_mul_v3,32,1,4,4,1,B->M->N线性映射+ASW滑窗蛇形(W=4),0,1,512,512,8192,128,1,双缓冲驻留当前tile输入,256,256,64,allocate(输入驻留L2吸收重复读),"direct_gm(输出直写GM, 输入优先驻留L2)",4,0,A0,1,1,1,0,0,0,16,True,2,"tile枚举: P=1, 有界枚举最优 mCnt=4 x nCnt=4 (tile 512x512, 每batch搬入256.0MB, r=0); Base tile 256x256 (L0C 单缓冲方形用满); L2场景: B_单batch可驻留(全驻留或单侧驻留+对侧滑窗) (V_in=2048.0MB, V_out=256.0MB, L2=128MB); 尾轮: r=0 无尾轮",2147483648,6442450944,0.00134217728,0.0012389328738461537,0.002581110153846154,0.0,0.0,2199023255552.0,0.004524739208954733,268435456,0.00016777216,0.0,0.004524739208954733,0.0,0.004524739208954733,MMAD,True,,计算Bound,"IterBatch/MergeBatch 进入条件均不满足, 回落 ASW_Basic; IterBatch未过: 3_L1驻留形态(四选一, 核心要求: 单batch核内零重复读); MergeBatch未过: 1_batch关系与每核份额: BatchA==BatchB 且 b_core=B/C>=2*b0; 2_L0C容量: 2*(b0*M)*(b0*N)*4B <= L0C; 2b_L0AB容量: 合并后 b0*M/b0*N 在最小K粒度下可驻留 L0A/L0B; 5_访存Bound: 2MN/(M+N) < R16/b0"
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
import unittest
|
||||
|
||||
from bmm_theory.models import BmmCase
|
||||
from bmm_theory.hardware import ASCEND950PR
|
||||
from bmm_theory.router import BranchRouter
|
||||
from bmm_theory.branches.merge_batch import MergeBatchBranch
|
||||
from bmm_theory.branches.iter_batch import IterBatchBranch
|
||||
@@ -108,12 +109,22 @@ class TestArbitration(unittest.TestCase):
|
||||
self.assertIn("L1绑定", detail)
|
||||
|
||||
def test_large_batch_mergebatch_wins(self):
|
||||
# 大 B + 小 MN + K 截断: MergeBatch 应胜 (v1.1 §4.5)
|
||||
case = mkcase(2048, 32, 32, 256)
|
||||
# 大 B + 小 MN + K 截断 + 合并 tile 效率差: MergeBatch 应胜
|
||||
# (issue#36: (2048,16,64,128) IterBatch A tile=4KB eff=0.25 vs 合并
|
||||
# 16KB eff=1.0, 效率节省 15.7us >> drain 0.17us; T_cmd=0 默认下仍胜)
|
||||
case = mkcase(2048, 16, 64, 128)
|
||||
self.assertTrue(MergeBatchBranch().analyze(case).capable)
|
||||
win, detail = self.mb.beats_iterbatch(case)
|
||||
self.assertTrue(win, detail)
|
||||
|
||||
def test_no_eff_diff_mergebatch_loses(self):
|
||||
# issue#36: K 截断但 IterBatch 单命令 tile 已达 16KB 饱和 (效率打平),
|
||||
# T_cmd=0 下命令节省为 0, 合并只剩 drain 惩罚 -> IterBatch 优
|
||||
# (原 t_cmd=50ns 时代的 MergeBatch 胜例 (2048,32,32,256), 语义迁移)
|
||||
case = mkcase(2048, 32, 32, 256)
|
||||
win, detail = self.mb.beats_iterbatch(case)
|
||||
self.assertFalse(win, detail)
|
||||
|
||||
|
||||
class TestTimingSanity(unittest.TestCase):
|
||||
"""时延模型自洽性."""
|
||||
@@ -385,34 +396,34 @@ class TestTransposeModeling(unittest.TestCase):
|
||||
|
||||
|
||||
class TestZeroCmdHandling(unittest.TestCase):
|
||||
"""T_cmd=0 (无命令时延/未标定) 时整链路不得除零/崩溃, 按策略优先 MergeBatch."""
|
||||
"""950PR 默认 T_cmd=0 (未标定, issue#36): 整链路不得除零/崩溃; 合并收益由
|
||||
搬移效率模型 (move_eff, 合并 tile 放大 b0 倍) 刻画, 不再设策略覆盖."""
|
||||
|
||||
def test_beats_iterbatch_policy(self):
|
||||
# T_cmd<=0: 阈值 +inf 不可除零; 合并后每核命令数更少即按策略判 MergeBatch 胜
|
||||
# (指令级收益未建模), 命令数打平/更多则恒劣 (issue#35 泛化口径)
|
||||
from bmm_theory.hardware import NpuSpec
|
||||
def test_beats_iterbatch_zero_cmd(self):
|
||||
# T_cmd=0: 命令节省项为 0, 由效率节省 vs drain 惩罚决定 (issue#36)
|
||||
from bmm_theory.branches.merge_batch import MergeBatchBranch
|
||||
spec0 = NpuSpec(t_cmd_ns=0.0)
|
||||
mb = MergeBatchBranch(spec0)
|
||||
# (b, m, n, k, MergeBatch应胜与否=合并后命令数更少)
|
||||
# (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)]
|
||||
mb = MergeBatchBranch() # 默认 spec 即 t_cmd_ns=0
|
||||
# (b, m, n, k, MergeBatch应胜与否=效率节省>drain惩罚)
|
||||
# (2048,16,64,128): iter A tile=4KB eff=0.25 vs 合并 16KB eff=1.0 -> 大胜
|
||||
# (2048,32,32,256): iter A tile=16KB 已饱和, 效率打平 -> drain 惩罚 -> 恒劣
|
||||
# (128,64,64,512): issue#35 第三情形 (dValue cap 截断, 命令/效率均打平) -> 恒劣
|
||||
# (256,128,128,4096): L1 绑定, tile 均 >=128KB 饱和 -> 恒劣
|
||||
cases = [(2048, 16, 64, 128, True), (2048, 32, 32, 256, False),
|
||||
(128, 64, 64, 512, False), (256, 128, 128, 4096, False)]
|
||||
for b, m, n, k, mb_wins in cases:
|
||||
win, detail = mb.beats_iterbatch(mkcase(b, m, n, k))
|
||||
self.assertEqual(win, mb_wins, f"{b},{m},{n},{k}: {detail}")
|
||||
self.assertIn("T_cmd=0", detail)
|
||||
self.assertIn("效率节省", detail)
|
||||
|
||||
def test_route_with_zero_cmd_prefers_merge(self):
|
||||
# T_cmd=0 且 K截断时路由应优先 MergeBatch (命令/指令次数少 b0 倍, 结构性收益)
|
||||
from bmm_theory.hardware import NpuSpec
|
||||
router = BranchRouter(NpuSpec(t_cmd_ns=0.0))
|
||||
r = router.route(mkcase(2048, 32, 32, 256)) # 大 B 小 MN 典型合并场景
|
||||
def test_route_with_zero_cmd_efficiency_decides(self):
|
||||
# 默认 t_cmd=0: 有效率低下的 IterBatch 小 tile case 由 MergeBatch 胜;
|
||||
# tile 均饱和的 case 由 IterBatch 胜 (drain 惩罚, 无策略覆盖)
|
||||
router = BranchRouter()
|
||||
r = router.route(mkcase(2048, 16, 64, 128)) # 效率差显著 -> MergeBatch
|
||||
self.assertEqual(r["branch"], "MergeBatch")
|
||||
self.assertIn("策略", r["arbitration"])
|
||||
self.assertIsNotNone(r["timing"])
|
||||
r2 = router.route(mkcase(2048, 32, 32, 256)) # tile 均饱和 -> IterBatch
|
||||
self.assertEqual(r2["branch"], "IterBatch")
|
||||
shapes = [(128, 64, 64, 512), (64, 64, 64, 8192), (512, 128, 128, 128),
|
||||
(128, 128, 128, 1024), (32, 4096, 4096, 4096)]
|
||||
for b, m, n, k in shapes:
|
||||
@@ -848,10 +859,12 @@ class TestIssue35(unittest.TestCase):
|
||||
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 增长, 节省固定)
|
||||
# B=128,M=1~16,N=128,K=512: issue#36 效率模型后, iter A tile=m*1KB 未饱和
|
||||
# (m<16), 合并 tile 4 倍大 -> 效率节省 ~0.61us 恒定, drain 随 M 线性增长;
|
||||
# m<=8 效率节省 > drain -> MergeBatch; m=16 iter tile 恰达 16KB 饱和 ->
|
||||
# 效率打平, drain 0.66us 决定 -> IterBatch
|
||||
expect = {1: "MergeBatch", 2: "MergeBatch", 4: "MergeBatch",
|
||||
8: "IterBatch", 16: "IterBatch"}
|
||||
8: "MergeBatch", 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']}")
|
||||
@@ -867,5 +880,56 @@ class TestIssue35(unittest.TestCase):
|
||||
self.assertEqual(m.group(1), r["branch"])
|
||||
|
||||
|
||||
class TestIssue36(unittest.TestCase):
|
||||
"""issue#36: 合并搬移效率建模 (tile=nValue*dValue*dt 放大 b0 倍) + t_cmd_ns=0.
|
||||
|
||||
用户澄清: MergeBatch 合并多 batch 左/右矩阵一起搬移, 单块 tile 放大 ->
|
||||
搬移效率更高, 即便 T_cmd=0 也有效益; 堆叠方向视转置 (A ND 非转置沿
|
||||
M(nValue), B ND 非转置沿 N(dValue)), 乘积口径不变。
|
||||
"""
|
||||
|
||||
def test_t_cmd_default_zero(self):
|
||||
self.assertEqual(ASCEND950PR.t_cmd_ns, 0.0)
|
||||
self.assertEqual(ASCEND950PR.t_cmd, 0.0)
|
||||
|
||||
def test_move_eff_curve(self):
|
||||
from bmm_theory.models import move_eff
|
||||
cap = ASCEND950PR.min_tile_size # 16KB 饱和点
|
||||
self.assertEqual(move_eff(cap, cap), 1.0) # 饱和
|
||||
self.assertEqual(move_eff(2 * cap, cap), 1.0) # 超出仍饱和
|
||||
self.assertAlmostEqual(move_eff(cap / 4, cap), 0.25) # 之下线性
|
||||
self.assertEqual(move_eff(0, cap), 1.0) # 零值守卫
|
||||
|
||||
def test_merge_eff_gain_beats_iterbatch(self):
|
||||
# (2048,16,64,128): iter A tile=4KB eff=0.25, 合并 A'=16KB eff=1.0
|
||||
# -> 效率节省 ~15.7us >> drain 0.17us, T_cmd=0 下 MergeBatch 大胜
|
||||
case = mkcase(2048, 16, 64, 128)
|
||||
mb = MergeBatchBranch().analyze(case)
|
||||
ib = IterBatchBranch().analyze(case)
|
||||
self.assertTrue(mb.capable and ib.capable)
|
||||
win, detail = MergeBatchBranch().beats_iterbatch(case)
|
||||
self.assertTrue(win, detail)
|
||||
self.assertLess(mb.timing.t_total, ib.timing.t_total)
|
||||
|
||||
def test_gm_bytes_unchanged_by_eff(self):
|
||||
# 效率模型只影响时间列: GM 字节量仍 = V_in (issue#31 口径不被破坏)
|
||||
for shp in [(128, 1, 128, 512), (2048, 16, 64, 128), (128, 64, 64, 512)]:
|
||||
case = mkcase(*shp)
|
||||
for br in (MergeBatchBranch(), IterBatchBranch()):
|
||||
r = br.analyze(case)
|
||||
if r.capable:
|
||||
self.assertAlmostEqual(r.timing.gm_read_bytes,
|
||||
case.input_bytes, places=3)
|
||||
|
||||
def test_iter_small_tile_slower_than_merge(self):
|
||||
# 用户 case m=1: IterBatch A tile=1KB eff=1/16 -> t_mte2_gm 显著高于
|
||||
# MergeBatch (A'=1.9KB eff=0.117), 且两者 GM 字节相同
|
||||
case = mkcase(128, 1, 128, 512)
|
||||
mb = MergeBatchBranch().analyze(case)
|
||||
ib = IterBatchBranch().analyze(case)
|
||||
self.assertGreater(ib.timing.t_mte2_gm, mb.timing.t_mte2_gm)
|
||||
self.assertEqual(mb.timing.gm_read_bytes, ib.timing.gm_read_bytes)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user