# PR352 SM90 Split L1/L2 MegaMoE 代码review报告

## 范围

- Worktree: `pr-352`
- HEAD: `655075ef3`
- 审查方式: 代码review
- 主题: SM90 MegaMoE 增强 — phase 分离、compact frontend、多 epilogue 策略

## 实现概述

### SM90 FP8 MegaMoE Enhanced Kernel

`deep_gemm/include/deep_gemm/impls/sm90_fp8_mega_moe.cuh` (~2507 lines)

本 kernel 是 pr-323 的重度增强版。核心创新是使用 **C++ 宏** 将同一个 kernel body 参数化为多种配置变体。

**warp 分工与线程布局（按 Phase 策略枚举）:**

**Compact 模式 (kCompactFrontendWarpgroup, topk=2, cluster=1, default):**

| Warp Index | 所属 Warpgroup | Role |
|---:|---|---|
| 0–1 (2 warps, 64 threads) | WG0 | Dispatch |
| 2–3 (2 warps, 64 threads) | WG0 | TMA A+SFA / B+SFB |
| 4–11 (8 warps, 256 threads) | WG1, WG2 | Math WGMMA + epilogue + combine |

**精确 warp 统计: 12 warps = 384 threads = 3 warpgroups**

**Serial/Wide N 模式 (BLOCK_M=32, topk≥8, cluster=2):**

| Warp Index | 所属 Warpgroup | Role |
|---:|---|---|
| 0–3 (4 warps, 128 threads) | WG0 | Dispatch |
| 4–7 (4 warps, 128 threads) | WG1 | TMA A+SFA / B+SFB / MMA issue / idle |
| 8–11 (4 warps, 128 threads) | WG2 | Math WGMMA + epilogue + combine |

**精确 warp 统计: 12 warps = 384 threads = 3 warpgroups**

**Serial/Wide N 模式 (BLOCK_M=64, topk≥8, cluster=2):**

| Warp Index | 所属 Warpgroup | Role |
|---:|---|---|
| 0–3 (4 warps, 128 threads) | WG0 | Dispatch |
| 4–7 (4 warps, 128 threads) | WG1 | TMA A+SFA / B+SFB / MMA issue / idle |
| 8–15 (8 warps, 256 threads) | WG2, WG3 | Math WGMMA + epilogue + combine |

**精确 warp 统计: 16 warps = 512 threads = 4 warpgroups** |

**Compact Frontend 模式 (dispatch+TMA 共享 WG0):**

当 `kCompactFrontendWarpgroup` 为 true 时，dispatch (2 warps) + TMA (2 warps) 共享一个 128-thread warpgroup:

| Config | Dispatch | TMA | Epilogue | Total Threads | Reg Budget |
|---|---|---|---|---|---|
| Compact (default) | 64 | 64 | 256 | 384 | 48+48+208→59,392 |
| Wide (≥128) | 128 | 128 | 256 | 512 | 48+40+208=64,512 |

**Phase 策略（通过宏模板参数选择）:**

| 模式 | 说明 |
|---|---|
| `kSerialNWarpgroups` | math warpgroups 串行处理 L1 再 L2 |
| `kWideNWarpgroups` | math warpgroups 使用更多 N block 并行 |
| `kFusedL1L2Warpgroups` | 同一 WG 同时处理 L1 和 L2（与 pr-323 类似） |
| `kUseMMASync` | 使用 MMA sync 路径（BLOCK_M=32 时启用） |
| `kCompactFrontendWarpgroup` | dispatch+TMA 共享 warpgroup |

**寄存器分配（宏推导）:**

```
kNumDispatchRegisters = 48
kNumNonEpilogueRegisters = kCompactFrontendWarpgroup ? 48 : 40
kNumEpilogueRegisters = (kSerialNWarpgroups or kWideNWarpgroups) ? 256
                      : ((kUseMMASync and BLOCK_M==32) ? 240 : 208)
```

Compact mode 下 non-epilogue 必须与 dispatch 使用相同的 register 数 (48)，因为它们共享同一个 warpgroup（WG0）。

**megamoe_sm90 branch 具体配置（来自 `csrc/jit_kernels/heuristics/mega_moe.hpp` 的 1025 行扩展启发式）:**

| Topk | Tokens | BLOCK_M | BLOCK_N | BLOCK_K | Epilogue Threads | Cluster | Compact | Phase | 备注 |
|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 所有 | 64 | 128 | 128 | 256 | 1 | Yes | Fused | |
| 8 | ≤128 | 32 | 128 | 128 | 128 | 2 | No | Serial NW | `kSerialNWarpgroups` 硬编码为 false，实际不可达 |
| 8 | ≤576 | 64 | 128 | 128 | 256 | 2 | No | Serial NW | 同上 |
| 8 | >576 | 64 | 256 | 128 | 256 | 2 | No | Serial NW | 同上 |
| 9+ | ≤128 | 32 | 128 | 128 | 128 | 2 | No | Serial NW | 同上 |
| 9+ | ≤576 | 64 | 128 | 128 | 256 | 2 | No | Serial NW | 同上 |
| 9+ | >576 | 64 | 256 | 128 | 256 | 2 | No | Serial NW | 同上 |

## 代码review发现

### 高: 宏驱动模板实例化导致编译膨胀

每次调用 `sm90_fp8_mega_moe` 会通过宏展开 4 个 kernel 实例（`INSTANTIATE_KERNEL_WITH_PHASE_POLICY` × 1 fuse + 1 serial_N + 1 wide_N + 1 mma_sync）。每个实例有独立的 `__launch_bounds__` 和 register 分配，JIT 编译时间较长。

### 中: Compact frontend 下 dispatch 使用 48 reg/warp — 仍然偏紧

dispatch warp 需要 rank round-robin 选择、SF copy 等复杂操作。48 reg/warp 可能在某些 shape 下触发 register spilling，但由于与 TMA warp 共享 WG0，无法单独增加而不破坏 budget。

### 中: Scheduler 保留严格整除约束

PR352 分叉自 #316（早于 PR347），因此其 scheduler (`mega_moe.cuh:38`) 仍使用 `kNumExpertsPerRank % kNumExpertsPerWave == 0` 的严格约束。PR347 的放宽修复（`> 0 && <=`）未被合入。对非 2 的幂 per-rank expert 数的 shape，可能触发编译期断言失败。

### 低: Compact 模式 register 余量尚充足

Compact 模式实际 register 消耗为 48×64+48×64+208×256=**59,392**（文档之前误写为 64,512），占预算约 90.6%，有约 5K register 余量。与 "tight" 的描述不同，实际还有一定 headroom。

### 中: 启发式文件增长到 1025 行，可维护性下降

`heuristics/mega_moe.hpp` 混合了 SM100 和 SM90 路径，且 SM90 部分包含大量硬编码的 topk/token 分支表。建议拆分为 `mega_moe_sm90.hpp` + `mega_moe_sm100.hpp`（类似 pr-360 的做法）。

### 低: Serial NW 模式下 `kNumEpilogueRegisters=256` 可能溢出

256 reg/warp × 256 epilogue threads = 65536，超过 64K reg budget。需要确认是否有其他约束（如减少 dispatch 线程数）来保证不溢出。

## 正面评价

- 宏驱动架构灵活，一个 kernel body 支持 4 种执行策略
- Compact frontend 优化了资源利用率（H100 上 dispatch 不需要独占 warpgroup）
- 多种 phase 策略覆盖了不同 token 量的最优执行路径
- Serial NW 模式的 epilogue 获得 256 reg/warp，适合计算密集场景

## 建议检查清单

- 验证 Serial NW 256 reg/warp 配置不超标
- 实测 compact frontend 下 dispatch warp 的 spilling 情况
- 考虑拆分 heuristics 文件降低维护成本
- 确认所有 4 种 phase 策略的 correctness 测试覆盖
