Skip to content

[Code Health] fully_distributed_within_core: alloc 单owner选举修复 heap 回收下溢;遗留精确依赖与 TensorMap overlap 待完善 #1202

Description

@poursoul

关联 PR:#1142fully_distributed_within_core runtime)。

背景

在 a2a3sim 上对 fully_distributed_within_core 做大规模验证(paged_attention_unroll,batch≥16,--use-example-exec-time busy-wait 回放路径)时,dist_alloc_tensors 会随机 SIGABRT。本 issue 记录已修复的根因与重构,并提出两点仍需完善的遗留问题。

已修复:alloc 缺少 single-owner 选举导致 heap 回收水位线无符号下溢

现象

  • a2a3sim、batch≥16、busy-wait 回放(--use-example-exec-time)下随机崩溃;OFF(真跑 kernel)与 tmr 同用例均不复现。
  • 表象是下游 get_refalways_assert(index < output_count_) 失败 → terminate → SIGABRT。

根因

heap reclaim back-pressure 用了无符号减法 heap_next - vend[F-H] 判断 live window 是否超过 ring。dist_alloc_tensors 此前由每个 core 无条件重放(不像 dist_submit_implis_winner 选举),因此当某个 core 的重放进度落后全局完成前沿 F 超过 H 个 task 时,会出现 heap_next < vend[F-H],无符号减法回绕到约 2^64 → 误判 "heap ring too small" → set_fatal(),随后 alloc 返回空 TaskOutputTensors{},下游 get_ref 即断言失败崩溃。

只有 busy-wait 回放路径在 batch≥16 触发:真跑 kernel 时各 core 的完成前沿足够接近,没有 core 会落后超过 H

修复(已在 PR #1142 重构)

dist_alloc_tensors 引入与 dist_submit_impl 相同的 single-owner 选举:

  • materialize 输出 + producer-map 登记仍每核执行(保持确定性重放一致);
  • 之后用一条新的 alloc_cursor 做 claim 选出唯一 owner;
  • 只有该 owner 执行 reclaim back-pressure 并发布完成标志

owner 必然处于/领先于完成前沿(它认领的 task 尚未完成,故 F < N),因此 window 减法不再可能下溢,无需额外的算术保护。把 materialize 提前到(现在仅 owner 执行的)back-pressure 之前,也使真正的 fatal 返回已物化的 result,而非此前会触发断言的空 result。


遗留待解决(可能已在设计文档中作为 feature/limitation 提出)

1. 依赖跨度用常数 H 近似,需要精确依赖 + 配套的内存复用管理

当前用依赖跨度上界 HkHDefault=64PTO_DIST_H 覆盖)来界定"某 producer 的最后消费者 id ≤ producer id + H",并据此推导 reclaim 水位线 R = F - H(见 docs/fully_distributed_within_core.md §依赖跨度/回收)。但实际 task 的依赖跨度可以很大且差异显著,常数 H 只是保守近似:

  • H 取小 → 可能在真实消费者读取前就回收了 producer 的堆区(运行期 fatal "heap span exceeded");
  • H 取大 → live window 占用过多 ring、削弱回收效率。

需要精确的 per-task 依赖区间(而非全局常数),以及与之配套的内存复用/回收管理机制,让回收水位线按真实依赖推进。

2. TensorMap.lookup 的 overlap 判断过于简单,且只返回单个前驱(无法支持 partial update 的多前驱)

dist_engine.cppMapEntry::lookup

  • overlap 判断仅为简单区间相交 lo < e.hi && e.lo < hi
  • 每个 tensor 只返回 MAX(最新)的一个 overlapping producer(return best)。

但在 partial update 场景下,一个 INPUT/INOUT 区域可能由多个前驱分别写入其不同子区间,正确的 fan-in 应解析出全部相关 producer,而非只取最新一个,否则依赖图不完整、可能在前驱未完成时就执行消费者。

建议参照 tensormap_and_ringbuffer(tmr)的 overlap 逻辑完善:采用 tmr 的区域重叠判定方式,并让 lookup 支持返回多个 partial 前驱。

相关代码:

  • src/a2a3/runtime/fully_distributed_within_core/runtime/dist_engine.cppMapEntry::lookupdist_alloc_tensors、reclaim back-pressure)
  • 参考:src/a2a3/runtime/tensormap_and_ringbuffer/runtime/(overlap / 多前驱解析)

Metadata

Metadata

Assignees

No one assigned

    Labels

    code healthTechnical debt, robustness, code quality

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions