diff --git a/BMM/BMM_Theory/docs/04_差异对照_bmmv3_vs_BMM_Theory.md b/BMM/BMM_Theory/docs/04_差异对照_bmmv3_vs_BMM_Theory.md new file mode 100644 index 0000000..dc3784e --- /dev/null +++ b/BMM/BMM_Theory/docs/04_差异对照_bmmv3_vs_BMM_Theory.md @@ -0,0 +1,175 @@ +# bmmv3 vs BMM_Theory 差异对照 + +> 对照对象:`bmmv3/bmmv3/bmmv3_arch35_branch_checker.py`(下称 **bmmv3**)与本仓库 `bmm_theory/branches/merge_batch.py` + `iter_batch.py`(下称 **BMM_Theory**)。 +> 写作目的:说清两版"是什么关系、差在哪、各自什么时候用、该互相吸收什么"。 + +--- + +## 0. 一句话结论 + +**两版不是竞争关系,是互补关系。** + +- **bmmv3** = 现有算子源码行为的**预测器/对拍器**(source-of-truth 是 `batch_matmul_v3_mergebatch_basicapi_tiling.cpp` / `iterbatch_tiling.cpp`); +- **BMM_Theory** = 理论最优实现的**推导器**(source-of-truth 是《BMM算子优化分析 v0.98》《MergeBatch_vs_IterBatch分析 v1.1》)。 + +要"知道现有 kernel 实际会怎么跑"→ 用 bmmv3;要"知道理论上应该怎么跑最优"→ 用 BMM_Theory。 + +--- + +## 1. 根本定位差异 + +| 维度 | bmmv3 | BMM_Theory | +|---|---|---| +| 目的 | 判断 case 能否进**现有源码**的 `MERGE_BATCH_BASICAPI` / `ITER_BATCH` | 推导 case 的**理论最优**实现方案 | +| 依据 | ops-nn 源码逐条件还原 | 理论文档推导 + 硬件容量/带宽约束 | +| tile 语义 | 按源码硬编码(ping_pong 开关、step 幂次搜索) | 按理论容量极限 + 生成后自检 | +| 时延模型 | 三行带宽公式(CUBE/FIXP/MTE2 各一行) | 分阶段 max(MMAD,MTE2,FIXPIPE)+drain,对齐 v1.1 | +| 分支覆盖 | 仅 MergeBatch + IterBatch | 六分支全(转Matmul/特殊/MergeBatch/IterBatch/StreamK/ASW_Basic) | +| 输入校验 | 无(静默接受非法输入) | `__post_init__` 明确报错(issue#15) | +| 生成后自检 | 无 | constraints.py 同源校验(issue#5) | + +--- + +## 2. MergeBatch 分支逐项对照 + +### 2.1 准入条件 + +| 条件 | bmmv3 | BMM_Theory | 差异说明 | +|---|---|---|---| +| batch 关系 | A/B 4 个 batch 轴完全相等 | BatchA==BatchB | bmmv3 更严(源码实现细节) | +| 每核 batch 下限 | `min_batch_l0=4`(每核≥4 batch) | `b_core ≥ 2*b0`(b0≥2 即每核≥4) | 等价,bmmv3 硬编码 4,我们参数化 | +| L0C 容量 | `l0cSize = tempAlignM×tempAlignN×4×l0c_factor ≤ L0C` | `2×(b0·M)×(b0·N)×4 ≤ L0C` | 一致(l0c_factor=2 即双缓冲) | +| L0A/L0B 容量 | 准入条件 21/22 查(`al0Size/bl0Size`) | **b0 计算时显式收敛(issue#13)** | **我们更完整**——bmmv3 只在准入查,没在 b0 计算里收敛 | +| K 对齐下限 | `alignK ≥ merge_min_align_k=64` | 无 | bmmv3 源码特有 | +| M≤N 约束 | 有(条件 13) | 无 | bmmv3 源码特有(实现限制,非理论必要) | +| 转置 view | 非连续转置 view 排除 | 不建模 | bmmv3 源码特有 | +| bias | `has_bias=false` | 不建模 | bmmv3 源码特有 | +| 访存 Bound | `2MN/(M+N) < 607/2`(经验常数) | `2MN/(M+N) < R16/b0`(R16=算存比) | **我们更通用**——607.5 是 R16 在 fp16 下的数值实例,fp32 时 R16 减半但 bmmv3 不会 | + +### 2.2 b0 计算 + +``` +bmmv3: b0 = min(L0C/(2·M·N·4), ceil(B/C), 607.5·(M+N)/(2·M·N)) +我们: b0 = min(√(L0C/(8MN)), R16·(M+N)/(2MN), √(L0A/(2·M·16·dt)), √(L0B/(2·N·16·dt)), b_core) 取因子 +``` + +**关键差异**:我们多了 L0A/L0B 上限(issue#13),bmmv3 靠 `min_batch_l0=4` 间接保证 L0A/L0B 不溢出,但不如显式约束通用(b0=2 时 bmmv3 的间接保证失效)。 + +### 2.3 KL0/KL1 计算 + +| | bmmv3 | BMM_Theory | +|---|---|---| +| KL0 | `floor_align16(min(L0A/(2·b0·M·dt), L0B/(2·b0·N·dt)))` | 同(`align_down(min(...), fractal)`) | +| KL1 | `ceil_align16(min(K, 512/dt, L1/(2·b0·(M+N)·dt)))`,不满足 L1 则减 16 循环 | `align_down(min(k_l1_star, K, dvalue_cap), fractal)` | +| 实现风格 | 源码试探式(ceil 后逐步减) | 理论反推式(直接 align_down) | + +**差异说明**:bmmv3 的"ceil 后减 16 循环"是源码实现细节(为了向上对齐后再试探),理论反推直接用 `align_down` 即可,结果等价但我们更简洁。 + +--- + +## 3. IterBatch 分支逐项对照 + +### 3.1 准入条件 + +| 条件 | bmmv3 | BMM_Theory | +|---|---|---| +| 每核 batch | `floor(B/C) ≥ 1` | `b_core ≥ 1`(ceil) | 一致 | +| 负载均衡 | `B mod C == 0` 或 `≥ 26`(硬编码) | `B mod C == 0` 或 `≥ min_core_num`(参数化) | **我们更通用** | +| L1 形态 | a/b/c1/c2/d 五种 | a/b/c/d 四种 | **bmmv3 更细**(c 拆 c1/c2) | + +### 3.2 c 形态处理 + +**bmmv3**: +- c1:MK 整体驻留 + KN/step 分块 +- c2:KN 整体驻留 + MK/step 分块 +- step 按 2/4/8/16… 幂次递增遍历取最大 + +**BMM_Theory**: +- c 形态统一:"驻留较小侧 + 对侧切 K" +- k_l1 连续反推:`k_l1 = (budget - resident) / (other·dt) / 2` + +**差异说明**:bmmv3 的 step 幂次搜索是源码为了 tiling 生成方便做的离散化;理论极限下 k_l1 连续取最优即可。**做理论推导用我们的,做源码对拍用 bmmv3 的。** + +### 3.3 d 形态处理 + +**bmmv3**:`step_d` 由 16KB 和 128B 两条规则推导,`KL1 = ceil_align16(K/step_d)`,不满足 L1 则减 16 循环。 + +**BMM_Theory**:`k_l1 = align_down(L1/(2·(M+N)·dt), fractal)`,直接反推。 + +**差异说明**:同上,bmmv3 是源码试探式实现,我们是理论反推。 + +--- + +## 4. 时延模型对照 + +| | bmmv3 | BMM_Theory | +|---|---|---| +| CUBE | `2·B·M·K·N / (MAC_TFLOPS·1e6)` | `2·b_core·M·N·K / q16`(单核) | +| MTE2 | `(2·M·K + 2·K·N)·B / (MTE2_BW·1e6)` | 分 GM/L2 两段 + T_cmd + drain | +| FIXP | `2·M·N·B / (FIXP_BW·1e6)` | `b_core·M·N·out_dtype / bw_pc` + unitflag | +| 流水掩盖 | 无 | max(MMAD,MTE2,FIXPIPE) + drain | +| 分支仲裁 | 无 | MergeBatch vs IterBatch 谁优 | + +**差异说明**:bmmv3 的时延是纯带宽粗估(三行公式),我们做分阶段 + drain + 仲裁,能定位瓶颈。 + +--- + +## 5. 各自适用场景 + +| 场景 | 推荐 | +|---|---| +| 预测现有 kernel 实际行为(对拍) | **bmmv3** | +| 推导理论最优方案(设计) | **BMM_Theory** | +| 分析瓶颈(MTE2/Cube/Fixpipe 谁卡) | **BMM_Theory**(bmmv3 无瓶颈分析) | +| 验证源码准入条件是否正确 | **bmmv3**(BMM_Theory 不管源码现状) | +| 大批量 case 筛选(XLSX 原表追加) | **bmmv3**(我们暂无 XLSX) | + +--- + +## 6. 可吸收点清单 + +### 6.1 bmmv3 → BMM_Theory(我们该补的) + +| 项 | 优先级 | 状态 | +|---|---|---| +| fp4(0.5B)dtype 支持 | 高 | ✅ **已补(本期)**——`DTYPE_BYTES` 加 `"fp4": 0.5` / `"fp4_e2m1": 0.5`,`dtype_bytes()` 返回 float | +| 转置对 dValue/base_k 的影响建模 | 高 | ✅ **已补(本期)**——MergeBatch 加条件 6(A 转置对齐),IterBatch dValue 判定按转置调整连续维 | +| XLSX 原表追加输出 | 中 | 待做 | +| c1/c2 的 step 幂次搜索 | 低 | 不做(理论极限不需要离散化) | + +**fp4 已补细节**: +- `models.py`: `DTYPE_BYTES` 加 `"fp4": 0.5` / `"fp4_e2m1": 0.5` +- `dtype_bytes()` 返回类型改为 `float`(兼容 0.5) +- `dtype_in_bytes`/`dtype_out_bytes` 属性返回类型改为 `float` +- 测试:`TestFp4Support` 3 个用例 + +**转置建模已补细节**: +- **MergeBatch**(`merge_batch.py`):新增条件 6——A 转置且 M>1 时 `tempAlignM = b0 * alignM`,校验 L0A 容量 +- **IterBatch**(`iter_batch.py`):dValue 判定按转置调整连续维——A 不转置判 `K*dt`,A 转置判 `M*dt`;B 不转置判 `N*dt`,B 转置判 `K*dt` +- 测试:`TestTransposeModeling` 3 个用例(含 A 转置大 M 小 K 通过、A 不转置小 K 失败的边界 case) + +### 6.2 BMM_Theory → bmmv3(他们可参考的) + +| 项 | 说明 | +|---|---| +| 分支仲裁 | MergeBatch vs IterBatch 谁优的判断 | +| 时延 drain/流水掩盖 | 三行公式 → 分阶段 max + drain | +| 生成后自检 | 生成即输出 → 生成后跑约束校验 | +| L0A/L0B 的 b0 显式收敛 | issue#13:b0 计算时直接纳入 L0A/L0B 上限 | +| 输入校验 | issue#15:非法维度/dtype 明确报错 | + +--- + +## 7. 结论 + +两版**互补不替代**。bmmv3 是"源码行为预测器"(对拍用),BMM_Theory 是"理论最优推导器"(设计用)。 + +**已吸收**:fp4 支持 + 转置对 dValue 的建模(本期补入)。 + +**不建议吸收**:c1/c2 的 step 幂次搜索(源码离散化细节,理论推导不需要)。 + +**待考虑**:XLSX 输出(如用户需要)。 + +--- + +*版本:v1.0 | 2026-09-03 | 基于 BMM_Theory 最新版(含 issue#11-#16 修复)与 bmmv3 最新版对照*