Files
CelerisLab/research/repair-2026-10-10/repair-state.md
T

76 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 状态与对象修复报告
2026-10-10,state agent。按用户新授权实施局部修复;未实现 jet/AMR,未改外部 DynamisLab、原始生成头或 PTX。Simulation 集成由 root 负责。
## 范围与依据
已读 `BRIEF.md` 与 `.github/skills/lbm-ref-architecture-guard/SKILL.md`,复查当前 public API→ObjectManager→patch/field→checkpoint 链及 git 历史 `987566c`(runtime body sync)、`04c2bc7`(obs interval)。保留已有 runtime pending/discard 和 sync 重编号设计。物理约束为已有 D2Q9 topology patch、FP32/FP16S、两种 streaming 的地址/编码/阶段不变量;不以未知生产 Re/Ma 阻碍修复这些代数错误。
编码与阶段参考:
- `ref/FluidX3D/src/lbm.cpp:409–414`:FP16S 存储乘 32768、读回除 32768;host 局部 patch 也必须走同一编码。
- `ref/FluidX3D/src/kernel.cpp:1332–1346`:Esoteric Pull 的 load/store 空间映射和时间奇偶不同;推进 store 不是同 count 的读写逆。
- `ref/FluidX3D/src/kernel.cpp:1141–1154`:新流体邻域只从 fluid donor 构建宏观量;本次保留原 BFS 方案,修正其实际读取布局。
- `ref/FluidX3D_analysis.md` §2.1/2.2:本地设计背景;核实公式以实际参考代码及本库 descriptors/storage 为准。
- PyCUDA async H2D/D2H 要求 page-locked host buffer。永久测试以拒绝 pageable async 的 driver double 验证调用契约;实际 GPU 验证由 root 统筹。
## 逐项处置
| 审查项 | 处置 | 具体边界 |
|---|---|---|
| STATE-01 Q-major vs AoS | fixed | body patch 全部按 `field.ddf.reshape(nq,n)[:,cell]` 访问。EsoPull compact scratch 仍是 cell-major;root 修正 scatter/gather 转换 |
| STATE-02 shift/FP16 越界 | fixed | field `_encode_ddf` 是整场/局部编码共用实现;patch 按方向与连续 cell 段上传,用实际 store_bytes,未改 cells 的 GPU 字节保持原样 |
| STATE-03 force action 丢失 | fixed | set_force 同时更新现有 force-region `state.vx/vy` aliases;set_body_state 同步 omega。全 action refresh、重编号与 checkpoint 不再丢另一对象控制;未新建第三份控制架构 |
| STATE-04 pre-init ID holes | fixed with explicit ID rule | 立即 remove 后将剩余 registry dense 重编号,刷新 action;已有 runtime sync 重编号不变。之前返回的 numeric IDs 失效,由公开 remove 文档说明 |
| STATE-05 checkpoint state/geometry/action | fixed, versioned | v2 保存实际 geometry/role/projection 指纹、host state/control、runtime params、已应用 device action 与 obs interval;不同几何先拒绝,匹配几何重建 compact lists/action。相同 count 不再充当 geometry 相等证明 |
| STATE-06 same-step cache | fixed | load 后始终 invalidate_host_ddf_cache,即使恢复 step 等于缓存 step |
| STATE-07 field snapshot parity | fixed; field-only design retained | snapshot 不回退 clock/body/control。EsoPull 保存 same-count next-pull 物理分布,restore 按当前 count 编码;direct field EsoPull 调用缺 step_id 报错。精确时间回退用 checkpoint |
| STATE-08 overlay changes solid | fixed | 先合成 solid occupancy,再只对 fluid 加 sensor/force annotations;compact lists 过滤 solid,sensor count 按有效 footprint 更新;实际 fluid footprint 重叠的多个 force_region 明确拒绝,以免并行同 cell 写竞争 |
| STATE-09 async pageable buffers | fixed | action 使用持久 pinned staging;EsoPull scratch pinned,encode 完成后才 free;compact SoA stream upload 使用 pinned staging 并在返回前同步。无 stream 路径使用同步复制 |
`field` 的 GPU 入口添加 architecture 提供的 `context_bound`。root 将 `field.ctx` 绑定实例 owner;独立低层 field 未附 ctx 时保留“调用者已使 context current”的原约定,CPU driver-double 方法仍可运行。
## Checkpoint 兼容性与选择
v2 读档在 GPU 写之前检查:lattice/extent/precision/streaming/shifting,dense IDs、geometry/role、实际投影指纹、重建 flags、array shape/dtype 与非负 step。不同几何不自动替换用户 case;调用者需构造匹配 case。匹配状态恢复后重建 host action、compact lists、params 与 obs,缓存失效。已应用 device action 单独保存,以保留 host 新目标尚未上传时的 `run(upload_act=False)` 时序。runtime params、obs interval 与 object state/control 在设备写之前完成转换和有限性检查。
保留有意的 collision/LES 等 parameter-study restart。若 viscosity 改变,使用当前 config 的 omega;不让 saved omega 覆盖用户新黏性。相同黏性可恢复原 runtime omega/forcing。
安全 v1 兼容范围:内置 CircleGeometry 的 circle/sensor,位置/半径/type/flags 必须一致;缺失 obs 明确清零 interval。v1 force_region 未保存真实控制,拒绝该类型并给出具体错误,不虚构恢复值;custom geometry 也不猜测。v1 无法恢复它从未记录的任意 runtime param,未宣称旧档具有 v2 完整性。
snapshot 明确保留 field-only 公共语义:跨奇偶恢复保证所保存的 next-pull 物理 field,不恢复时间与控制,也不声称恢复 t=0 初始化的特殊 wall 分支或整个运行历史。禁止把它描述成完整 checkpoint。
## 改动文件
- `src/CelerisLab/body/ddf_patch.py`
- `src/CelerisLab/body/manager.py`
- `src/CelerisLab/body/preprocess/flag_overlay.py`
- `src/CelerisLab/lbm/field.py`
- `src/CelerisLab/lbm/curved_links.py`
- `src/CelerisLab/common/checkpoint.py`
- `tests/unit/test_state_regressions.py`
- `tests/integration/test_state_gpu.py`(13 个有界 GPU cases,交 root 运行)
新增测试使用真实 class/method 与真实 h5py HDF5。仅 driver/device allocation/kernel invocation 用隔离 double;不是 AST 摘录、不是另写一份 host 实现。double 对每次复制检查 allocation 边界,async 时检查 pinned 来源;snapshot 的简化 parity 映射只检查 host 阶段协议,真实 EsoPull CUDA 数学由 numerical 的 actual-header 测试和 root GPU 验证负责。
## 实测
导入来源已核对为 `/home/frank14f/CelerisLab/src/CelerisLab/__init__.py`,解释器明确为 `/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python`。
```
PYTHONPATH=/home/frank14f/CelerisLab/src \
/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python -m pytest \
tests/unit/test_state_regressions.py tests/unit/test_body_flags.py \
tests/unit/test_pending_edits.py tests/unit/test_sync_plan.py -q
```
**60 passed**(0.38 s,2026-10-10 最终 state 范围)。覆盖四种 precision×shift、Q-major BFS donor、无关 cell 字节、control→remove→sync、双顺序 overlay、有效 sensor counts、force overlap rejection、pinned action/scratch/compact、field-only snapshot parity、checkpoint v2 roundtrip/拒绝前零设备写/同step缓存/黏性参数研究及 v1 兼容范围、malformed metadata 的拒绝前零设备写、host pending/device applied action 分别恢复。
## 交叉复核与剩余验证
已复核 numerical 的 same-time store 使用与 load 相同的 `src_cell + slot`,Encode 不碰撞且先转 shifted 表示;PrepareEsoPullWalls 在 curved apply 和 in-place streaming 之前同 stream 完成,pre-stream donors 不再被后续写入污染。接受其阶段修复。architecture 已独立复核 checkpoint/context/lifetime,接受核心修复;指出的 metadata late coercion 已修复并加入回归。其指出的 interval checkpoint obs 计数与外部 stream 同步由 root 修复。numerical 也独立读 field/checkpoint 并重跑 state 回归通过。
本 agent 独立重跑 `tests/unit/test_numerical_operators.py`:**36 passed**(28.57 s),支持上述跨模块复核。本 agent 未运行 GPU;root 已收到 ready 通知,并负责真实 CUDA、集成、资源关闭与 TRON handoff。D3 geometry topology patch 仍未实现,不在此修复中伪装支持。BFS 仍是已有的新流体初始化策略,本轮未给动态运动边界新增守恒算法或稳定性保证。
GPU 专项测试覆盖:4 个 EsoPull snapshot precision×shift 跨一步 parity;4 个 shifted topology add/remove;2 个两布局 checkpoint bitwise continuation;geometry mismatch 不修改设备;interval checkpoint observation normalization;host pending/device applied controls 的 upload_act=False 续跑。这里记录测试定义,不提前宣称 GPU 通过;实测由 root 最终日志给出。