Fix #37: ASW_Basic 尾轮残余 drain 闭式化 (方案甲)
- P1 (bug, evaluate 路径): A0+r>0 的 t_drain 由"全 case 三级 max" (t_total≈2x 稳态) 修为块级残余 (1-ρ)·T_block (v1.5 §3.3) - P2: 周长型主导 + r>0 补尾轮残余: A1b (√ρ−ρ)·T_load; 方案B (√(n_wave(n_wave−1+ρ))−(n_wave−1+ρ))·T_load (v1.5 §5); 面积型与 r=0 残余恒 0 (§4.3 严格相等), recommend 稳态主口径不变 - 块级三段时延抽取 _block_times, _decide_tail 与 evaluate 同源 - P3/P4 仅文档标注 (docs/02_分支理论/06 §3): 首块填充/末块排空 (UnitFlag 16-granule 级小量, 量级未标定) 与尾轮重切流量放大 (√g / 1/√ρ) 不入模型 - tests: TestIssue37 七例锁数值 (81/81 通过); examples 44 行 0 diff; 压力回归 seed7/6000+seed2024/4000 干净 (0 崩溃/NaN/违规/GM<V_in)
This commit is contained in:
@@ -931,5 +931,102 @@ class TestIssue36(unittest.TestCase):
|
||||
self.assertEqual(mb.timing.gm_read_bytes, ib.timing.gm_read_bytes)
|
||||
|
||||
|
||||
class TestIssue37(unittest.TestCase):
|
||||
"""issue#37: ASW_Basic evaluate 尾轮残余 drain 闭式化 (方案甲).
|
||||
|
||||
- P1: A0 + r>0 的 drain 由"全 case 三级 max"(≈2x 稳态) 修为 (1-ρ)·T_block;
|
||||
- P2: 周长型 A1b/方案B 补残余 (√ρ−ρ) / (√(n_wave(n_wave−1+ρ))−(n_wave−1+ρ))·T_load;
|
||||
- 面积型 A1b/方案B 与 r=0 残余恒 0 (v1.5 §4.3 严格相等);
|
||||
- 块级三段时延与 _decide_tail 同源 (_block_times, L2 命中口径).
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
from bmm_theory.branches.asw_basic import AswBasicBranch
|
||||
self.br = AswBasicBranch()
|
||||
self.s = ASCEND950PR
|
||||
|
||||
@staticmethod
|
||||
def _plan(case, sm, sn, m_cnt, n_cnt, strategy, r, n_wave):
|
||||
from bmm_theory.models import ImplPlan
|
||||
return ImplPlan(case_id=case.case_id, branch="ASW_Basic",
|
||||
used_core_num=32, m_cnt=m_cnt, n_cnt=n_cnt,
|
||||
single_core_m=sm, single_core_n=sn,
|
||||
single_core_k=case.k, k_l1=128,
|
||||
base_m=256, base_n=256, base_k=64,
|
||||
tail_strategy=strategy, tail_block_cnt=r,
|
||||
tail_wave_num=n_wave, fixpipe_unitflag=True,
|
||||
out_dtype_bytes=case.dtype_out_bytes)
|
||||
|
||||
def test_block_times_formula(self):
|
||||
# 块级三段 = v1.5 §2.1 口径 (k_L1 约掉, L2 命中带宽)
|
||||
case = mkcase(3, 1024, 1024, 1024)
|
||||
t_mm, t_mv, t_fx = self.br._block_times(case, 256, 256)
|
||||
self.assertAlmostEqual(t_mm, 2 * 256 * 256 * 1024
|
||||
/ self.s.q_cube("bf16", "bf16"))
|
||||
self.assertAlmostEqual(t_mv, 1024 * (256 + 256) * 2 / self.s.bw_l2_pc)
|
||||
self.assertAlmostEqual(t_fx, 256 * 256 * 2 / self.s.bw_pc)
|
||||
|
||||
def test_a0_drain_is_block_level_residual(self):
|
||||
# P1 修复: A0 + r>0 的 drain = (1-ρ)·T_block (修复前误用全 case 三级
|
||||
# max -> t_total ≈ 2x 稳态)
|
||||
case = mkcase(3, 1024, 1024, 1024)
|
||||
p = self._plan(case, 512, 128, 2, 8, "A0", r=16, n_wave=2)
|
||||
t = self.br.evaluate(case, p)
|
||||
t_block = max(self.br._block_times(case, 512, 128))
|
||||
self.assertAlmostEqual(t.t_drain, (1 - 16 / 32) * t_block)
|
||||
self.assertAlmostEqual(t.t_total, t.t_steady + t.t_drain)
|
||||
self.assertLess(t.t_drain, t.t_steady) # 不再 ~2x 稳态
|
||||
|
||||
def test_area_dominated_tail_residual_zero(self):
|
||||
# 面积型 (MMAD/FIX 主导): A1b/方案B 残余恒 0 (v1.5 §4.3 严格相等)
|
||||
case = mkcase(3, 1024, 1024, 1024)
|
||||
for strat in ("A1b", "方案B"):
|
||||
p = self._plan(case, 512, 128, 2, 8, strat, r=16, n_wave=2)
|
||||
t = self.br.evaluate(case, p)
|
||||
self.assertEqual(t.t_drain, 0.0, strat)
|
||||
self.assertAlmostEqual(t.t_total, t.t_steady)
|
||||
|
||||
def test_perimeter_a1b_residual(self):
|
||||
# P2: 周长型 (块级 MTE2 主导) + A1b: drain = (√ρ−ρ)·T_load
|
||||
case = mkcase(1, 640, 1408, 4096)
|
||||
t_mm, t_mv, t_fx = self.br._block_times(case, 64, 64)
|
||||
self.assertGreater(t_mv, max(t_mm, t_fx)) # 确认为周长型前提
|
||||
p = self._plan(case, 64, 64, 10, 22, "A1b", r=28, n_wave=7)
|
||||
t = self.br.evaluate(case, p)
|
||||
rho = 28 / 32
|
||||
self.assertAlmostEqual(t.t_drain, (rho ** 0.5 - rho) * t_mv)
|
||||
self.assertAlmostEqual(t.t_total, t.t_steady + t.t_drain)
|
||||
|
||||
def test_perimeter_planb_residual(self):
|
||||
# P2: 周长型 + 方案B: drain = (√(n_wave(n_wave−1+ρ))−(n_wave−1+ρ))·T_load
|
||||
case = mkcase(1, 640, 1408, 4096)
|
||||
p = self._plan(case, 64, 64, 10, 22, "方案B", r=28, n_wave=7)
|
||||
t = self.br.evaluate(case, p)
|
||||
t_mv = self.br._block_times(case, 64, 64)[1]
|
||||
rho, x = 28 / 32, 7 - 1 + 28 / 32
|
||||
self.assertAlmostEqual(t.t_drain, ((7 * x) ** 0.5 - x) * t_mv)
|
||||
self.assertGreater(t.t_drain, 0.0)
|
||||
|
||||
def test_r0_drain_zero(self):
|
||||
case = mkcase(3, 1024, 1024, 1024)
|
||||
p = self._plan(case, 512, 128, 2, 8, "A0", r=0, n_wave=2)
|
||||
self.assertEqual(self.br.evaluate(case, p).t_drain, 0.0)
|
||||
|
||||
def test_make_plan_perimeter_a1b_end_to_end(self):
|
||||
# 端到端 (make_plan 自产方案): 瘦长 case 周长型 + ρ≥ρ_dv -> A1b,
|
||||
# drain 与闭式一致 (_decide_tail 与 evaluate 同源)
|
||||
case = mkcase(33, 16, 8192, 7168)
|
||||
p = self.br.make_plan(case)
|
||||
self.assertGreater(p.tail_block_cnt, 0)
|
||||
self.assertEqual(p.tail_strategy, "A1b", p.note)
|
||||
t_mm, t_mv, t_fx = self.br._block_times(
|
||||
case, p.single_core_m, p.single_core_n)
|
||||
self.assertGreater(t_mv, max(t_mm, t_fx)) # 周长型前提
|
||||
t = self.br.evaluate(case, p)
|
||||
rho = p.tail_block_cnt / 32
|
||||
self.assertAlmostEqual(t.t_drain, (rho ** 0.5 - rho) * t_mv)
|
||||
self.assertAlmostEqual(t.t_total, t.t_steady + t.t_drain)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user