Fix #27-#30: dtype感知算力(Cube/AIV速率表) / GM首读下限与整芯片字节列口径+设计文档 / Fixpipe输出落点R4(整case驻留L2否则直写GM) / MergeBatch Cube公式复核注释

- docs/05_L2驻留GM读写与dtype算力口径_设计分析.md: R1-R6公理、S_A/S_B/S_C场景、输出落点R4、dtype速率表(白皮书出处+待标定假设)、逐分支GM/L2归属表 (issue#29/#30 先文档后代码)
- hardware: CUBE_DTYPE_FACTOR(f16/bf16=1, fp8=2x, fp4=4x, fp32=1/2假设) + AIV_DTYPE_FACTOR + q_cube/aiv_elem_rate (issue#28)
- 全分支 t_mmad/t_comp/drain/尾轮主导项/θ_c/R16 语义按输入dtype取算力; 混精度取慢侧; StreamK归约保持fp32(AIV fp32部分和)
- Fixpipe输出落点R4: to_l2 <=> V_in+V_out(+workspace)<=L2; 否则直写GM计入共享总线; ASW场景改S_A整case全驻留(原单batch驻留判定漏计整case输出累积逐出)
- 字节列统一整芯片口径(gm/l2/fix/cube_flops), dma_cmd_count注明单核; GM>=V_in不变量入测试; MergeBatch每步flops=2(b0M)(b0N)K公式注释显式化(#27复核与CSV一致无数值改动)
- tests 39->49 全过; 双压力seed7/6000+seed2024/4000: 0违规/0占位/0NaN/0GM<输入; examples三件套重生成且可复现0diff
This commit is contained in:
2026-09-04 16:26:10 +08:00
parent 4843053ad3
commit b9e07edc1d
15 changed files with 793 additions and 239 deletions

View File

@@ -24,7 +24,19 @@ from __future__ import annotations
from dataclasses import dataclass
from .hardware import NpuSpec, ASCEND950PR
from .models import HardwareTiming
from .models import BmmCase, HardwareTiming
def output_to_l2(case: BmmCase, spec: NpuSpec = ASCEND950PR,
workspace_bytes: float = 0.0) -> bool:
"""Fixpipe 输出落点决策 (issue#30, 设计文档 docs/05 §4.2 R4).
to_l2 (输出写 L2 写口 5.2TB/s, GM 写流量 = 0, 异步回写不占算子时延)
⟺ 整 case 输入 V_in + 输出 V_out [+ StreamK workspace] ≤ L2
否则输出**直写 GM**: 输入优先驻留 L2 (输入存在重复读), 输出计入 GM
读写共享总线 (与读累加, issue#23).
"""
return (case.input_bytes + case.output_bytes + workspace_bytes) <= spec.l2_bytes
@dataclass
@@ -56,9 +68,11 @@ def eval_mte2(move: MoveInPlan, spec: NpuSpec = ASCEND950PR,
return t_gm, t_l2, t_gm + t_l2 + t_cmd, t_cmd
def eval_mmad(flops_per_core: float, spec: NpuSpec = ASCEND950PR) -> float:
"""Cube 计算时延: 单核计算量 / 单核算力."""
return flops_per_core / spec.q16 if flops_per_core > 0 else 0.0
def eval_mmad(flops_per_core: float, spec: NpuSpec = ASCEND950PR,
dtype_a=None, dtype_b=None) -> float:
"""Cube 计算时延: 单核计算量 / 单核 dtype 感知算力 (issue#28)."""
rate = spec.q_cube(dtype_a, dtype_b)
return flops_per_core / rate if flops_per_core > 0 else 0.0
def eval_fixpipe(bytes_per_core: float, to_l2: bool,
@@ -75,21 +89,24 @@ def eval_fixpipe(bytes_per_core: float, to_l2: bool,
def eval_streamk_reduce(tile_elems: float, grid_k: int, out_dtype_bytes: int,
spec: NpuSpec = ASCEND950PR) -> float:
spec: NpuSpec = ASCEND950PR, out_to_gm: bool = False) -> float:
"""StreamK 单 tile 归约时延 (v0.98 §七).
部分和 dtype = L0C dtype (4B, 防精度丢失), 驻留 L2, AIV 归约:
部分和 dtype = L0C dtype (4B, 防精度丢失), 驻留 L2, AIV 归约 (fp32 求和,
AIV 按 fp32 通量, 不随输入 dtype 变 — issue#28):
AIC 写部分和 grid_k x tile x 4B / W_L2
AIV 读回 grid_k x tile x 4B / W_L2
AIV 求和 grid_k x tile / Q_AIV
写回 tile x outB / W_L2
AIV 求和 grid_k x tile / Q_AIV(fp32)
写回 tile x outB / W (最终输出落点, issue#30):
整 case 可驻留 (S_A) 时 W = W_L2; 否则直写 GM (W = W_GM)
"""
b4 = 4
w_l2 = spec.bw_l2
w_out = spec.bw_gm if out_to_gm else w_l2
t_write_partial = grid_k * tile_elems * b4 / w_l2
t_read_back = grid_k * tile_elems * b4 / w_l2
t_sum = grid_k * tile_elems / spec.q_aiv
t_write_out = tile_elems * out_dtype_bytes / w_l2
t_write_out = tile_elems * out_dtype_bytes / w_out
return t_write_partial + t_read_back + t_sum + t_write_out