Fix #34: ASW_Basic 兜底恒出方案; 搬移效率下限不满足降级为 warning (不判违规)
- constraints.py: ASW_Basic/ASW_Basic_降核 的 dValue 效率下限不再计违规 (DMA 仍能工作只是效率低; 真正不可行的只有容量/核数硬约束); IterBatch/MergeBatch/StreamK 等有替代分支的分支仍按违规处理 (不满足条件不该进) - asw_basic 枚举尾部: 严格 256B 偏好无解 -> 放开约束4 按 128B 硬下限给最优可行 tile, note 标注"效率降级"; 128B 硬下限也不满足的极端形状 (如 N=8 int8, B 侧 dValue=8B 物理不可满足) 仍给 Base tile 方案 + 标注效率降级 (搬移效率崩塌) - evaluator advice / router 仲裁文案含"效率降级"提示 (plan.note 同步) - docs/06 Step1 增加"兜底分支恒出方案"段落 (效率降级 vs 违规的语义分层) - 回归: b32_m16_n8192_k7168 分解 = Base 16x1024 + tile 16x1024 + k_l1=112 (L1 双缓冲 ⌊L1/(2·(16+1024)·2)⌋16=112 反推) 入测试; 极端形状 feasible=True + 效率降级标注; 压力 10000 例 0 崩溃/0 NaN/0 硬违规/0 GM<V_in; examples 重生成 0 diff
This commit is contained in:
@@ -245,41 +245,51 @@ class AswBasicBranch(Branch):
|
||||
key = (traffic, -r) # 主键搬入量最小; 并列 r 最大
|
||||
if best is None or key < best[0]:
|
||||
best = (key, sm, sn, k_l1, mc_r, nc_r, traffic, r)
|
||||
if best is None:
|
||||
# 兜底: 放开约束 4 (Base 整数倍), 在 16 对齐网格上按硬下限 (dValue>=128B
|
||||
# 硬底 / L1 容量) 找最优可行 —— 极端形状 (如 M=2 与大 N/K 组合) 下
|
||||
# Base 粒度可能无可行解; 若仍无解则退回 Base tile 由自检标注违规
|
||||
dv_hard = s.dvalue_min # 128B 硬下限
|
||||
for sm in range(s.fractal, align_up(min(m, 1024), s.fractal) + 1, s.fractal):
|
||||
for sn in range(s.fractal, align_up(min(n, 1024), s.fractal) + 1, s.fractal):
|
||||
k_cap = int(s.l1_bytes / (2 * (sm + sn) * dt))
|
||||
k_l1 = align_down(min(k, k_cap), s.fractal)
|
||||
if k_l1 < s.fractal:
|
||||
continue
|
||||
dv_a = sm * dt if case.trans_a else k_l1 * dt
|
||||
dv_b = k_l1 * dt if case.trans_b else sn * dt
|
||||
if dv_a < dv_hard or dv_b < dv_hard:
|
||||
continue
|
||||
mc_r = ceil_div(m, sm)
|
||||
nc_r = ceil_div(n, sn)
|
||||
if b * mc_r * nc_r < c:
|
||||
continue
|
||||
traffic = k * dt * (nc_r * m + mc_r * n)
|
||||
r = (b * mc_r * nc_r) % c
|
||||
key = (traffic, -r)
|
||||
if best is None or key < best[0]:
|
||||
best = (key, sm, sn, k_l1, mc_r, nc_r, traffic, r)
|
||||
if best is None:
|
||||
# 极端兜底: 退回 Base tile (约束校验会标注违规, 方案不可行可人工处置)
|
||||
k_l1 = max(align_down(min(k, int(s.l1_bytes /
|
||||
(2 * (base_m + base_n) * dt))),
|
||||
s.fractal), s.fractal)
|
||||
return (base_m, base_n, k_l1, ceil_div(m, base_m), ceil_div(n, base_n),
|
||||
"枚举无可行候选, 退回 Base tile (自检会标注)")
|
||||
_, sm, sn, k_l1, mc_r, nc_r, traffic, r = best
|
||||
return (sm, sn, k_l1, mc_r, nc_r,
|
||||
f"P={p_min}, 有界枚举最优 mCnt={mc_r} x nCnt={nc_r} "
|
||||
f"(tile {sm}x{sn}, 每batch搬入{traffic/1048576:.1f}MB, r={r})")
|
||||
if best is not None:
|
||||
_, sm, sn, k_l1, mc_r, nc_r, traffic, r = best
|
||||
return (sm, sn, k_l1, mc_r, nc_r,
|
||||
f"P={p_min}, 有界枚举最优 mCnt={mc_r} x nCnt={nc_r} "
|
||||
f"(tile {sm}x{sn}, 每batch搬入{traffic/1048576:.1f}MB, r={r})")
|
||||
|
||||
# 情形 3: 放开约束 4 (Base 整数倍), 16 对齐网格 + 硬下限 (dValue>=128B) 再搜
|
||||
# —— 兜底分支恒出方案 (issue#34): 256B 偏好无解时按硬下限给最优可行 tile,
|
||||
# 标注效率降级 (搬移效率低于模型假设, 时延可能低估)
|
||||
dv_hard = s.dvalue_min # 128B 硬下限
|
||||
best2 = None
|
||||
for sm in range(s.fractal, align_up(min(m, 1024), s.fractal) + 1, s.fractal):
|
||||
for sn in range(s.fractal, align_up(min(n, 1024), s.fractal) + 1, s.fractal):
|
||||
k_cap = int(s.l1_bytes / (2 * (sm + sn) * dt))
|
||||
k_l1 = align_down(min(k, k_cap), s.fractal)
|
||||
if k_l1 < s.fractal:
|
||||
continue
|
||||
dv_a = sm * dt if case.trans_a else k_l1 * dt
|
||||
dv_b = k_l1 * dt if case.trans_b else sn * dt
|
||||
if dv_a < dv_hard or dv_b < dv_hard:
|
||||
continue
|
||||
mc_r = ceil_div(m, sm)
|
||||
nc_r = ceil_div(n, sn)
|
||||
if b * mc_r * nc_r < c:
|
||||
continue
|
||||
traffic = k * dt * (nc_r * m + mc_r * n)
|
||||
r = (b * mc_r * nc_r) % c
|
||||
key = (traffic, -r)
|
||||
if best2 is None or key < best2[0]:
|
||||
best2 = (key, sm, sn, k_l1, mc_r, nc_r, traffic, r)
|
||||
if best2 is not None:
|
||||
_, sm, sn, k_l1, mc_r, nc_r, traffic, r = best2
|
||||
return (sm, sn, k_l1, mc_r, nc_r,
|
||||
f"效率降级(放开约束4, dValue 按 128B 硬下限, 搬移效率低于模型假设, "
|
||||
f"时延可能低估): P={p_min}, mCnt={mc_r} x nCnt={nc_r} "
|
||||
f"(tile {sm}x{sn}, 每batch搬入{traffic/1048576:.1f}MB, r={r})")
|
||||
|
||||
# 情形 4: 极端兜底 —— 兜底分支恒出方案 (issue#34): 效率下限物理不可满足
|
||||
# 也照常给方案 + 标注效率降级 (搬移效率崩塌), 不判违规/不产 None
|
||||
k_l1 = max(align_down(min(k, int(s.l1_bytes /
|
||||
(2 * (base_m + base_n) * dt))),
|
||||
s.fractal), s.fractal)
|
||||
return (base_m, base_n, k_l1, ceil_div(m, base_m), ceil_div(n, base_n),
|
||||
"效率降级(极端形状: 效率下限物理不可满足, 搬移效率崩塌, 时延可能低估; "
|
||||
"方案供参考, 建议调整 dtype/布局或转置)")
|
||||
|
||||
def _swizzle_w(self) -> int:
|
||||
s = self.spec
|
||||
|
||||
@@ -85,7 +85,12 @@ def check_plan_constraints(case: BmmCase, plan: ImplPlan,
|
||||
|
||||
# --- dValue --- (issue#6 口径裁定: 只对"以 K 段为连续维"的方案生效)
|
||||
if _k_segment_is_contiguous(plan, case) and plan.k_l1 > 0:
|
||||
if plan.branch == "IterBatch" and plan.l1_form.startswith(("c_", "d_")):
|
||||
if plan.branch in ("ASW_Basic", "ASW_Basic_降核"):
|
||||
# issue#34: ASW 是兜底分支, 恒出方案; dValue 效率下限不满足只算**效率降级**
|
||||
# (plan.note 含"效率降级"标注, DMA 仍能工作只是效率低), 不判违规.
|
||||
# 真正不可行的只有容量/核数硬约束 (L0C/L0A/L0B/L1 超容, 核数超限).
|
||||
pass
|
||||
elif plan.branch == "IterBatch" and plan.l1_form.startswith(("c_", "d_")):
|
||||
# 转置感知判据与生成守卫/条件 4 同源 (issue#19):
|
||||
# dv_a = M*dt (A 转置) 或 k_l1*dt; dv_b = N*dt (B 不转置) 或 k_l1*dt;
|
||||
# 两侧连续维 dValue 均低于下限才算违规.
|
||||
|
||||
@@ -63,6 +63,9 @@ class PlanEvaluator:
|
||||
def _advice(self, case: BmmCase, plan: ImplPlan, res: EvalResult) -> str:
|
||||
t = res.timing
|
||||
tips = []
|
||||
if "效率降级" in plan.note:
|
||||
tips.append("效率降级标注 (plan.note): 搬移效率下限不满足 —— 方案照常给出 "
|
||||
"(兜底), 但实际效率低于模型假设, 时延可能低估; 建议调整 dtype/布局")
|
||||
if not res.feasible:
|
||||
tips.append("方案违反硬件约束, 需先修正: " + res.violations)
|
||||
bn = t.bottleneck
|
||||
|
||||
@@ -174,6 +174,9 @@ class BranchRouter:
|
||||
if violations:
|
||||
note = (note + " [自检违规: " + "; ".join(violations) +
|
||||
"] —— 方案生成存在缺陷, 需人工复核")
|
||||
# issue#34: 兜底分支 (ASW) 效率下限不满足时降级标注 (warning), 不判违规
|
||||
if result.plan is not None and "效率降级" in result.plan.note:
|
||||
note += " [效率降级标注: 搬移效率低于模型假设, 时延可能低估, 见 plan.note]"
|
||||
return {
|
||||
"branch": result.plan.branch if result.plan else "未知",
|
||||
"plan": result.plan,
|
||||
|
||||
Reference in New Issue
Block a user