Preserve bounded validation evidence and historical failures

This commit is contained in:
Frank14f committed 2026-10-15 10:13:51 +08:00
1 parent cdbb9c42f6
commit 263f3b0c7a
239 files changed
+74191

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
# J3 最小功能覆盖:运行前冻结
本轮唯一写入/执行者 root;仅新增独立验证脚本和本目录。257 个现有文件的 SHA256 已冻结于 baseline.json,含源码、旧测试、报告、日志、数据及真实 checkpoint;旧正例失败不改。固定已有 pycuda_3_10 解释器、当前仓库及进程 PYTHONPATH;每次科研命令核对 Python 包及 CUDA 源码来源。不安装依赖、不改生产公式、不提交推送、不访问其他项目、不联系外部评审。
GPU 只选空闲的 0。初查 GPU0 为 0%/9 MiB,无计算进程;GPU1 有 362 MiB Python 作业,本轮不使用。正式命令前再查。48×35×9×4×2=120960 字节双缓冲,加 flags 3360 字节、宏观缓存约 20 KiB/实例;顺序实例及小型审计模块,预算显存低于 1 GiB、CPU RSS 低于 512 MiB、输出低于 10 MiB。系统当前可用内存约 56 GiB,GPU0 总显存 16 GiB。临时编译目录使用现有编译器的独立构建和清理;不改 PyCUDA 环境。
## 固定顺序与判据
1. 从既有 end-21280.h5 恢复,SHA256 `19a94e9e8db6dd9ac981effe06032c351992250b58768d9c090409193893d588`。校验配置、运行参数及 postcollision g(t) 分布阶段。A 在未推进时另存本轮 checkpoint,再推进 16 步到 21296;关闭 A 后新建 B,从本轮 checkpoint 独立恢复并推进 16 步。逐字节比 DDF/temp/flags,比较 step_count、config/runtime;不声称拥有历史不间断参照。失败或非有限即停,不继续零/负例。
2. 同 48×35/W16、rho1、nu.1、U0、top reservoir,A=0,固定 64 步。每步检查有限性、rho/speed/质量界;记录初始化及 64 步的质量、速度、边界和密度。zero_speed≤2e-6;零参考相对通量为 N/A;不宣称完整稳态通过,不额外做预算推进。
3. 唯一负例 A=−.002,同原参数,固定最多 40×519=20760 主轨迹步,不提前以某个短窗口改判。每步检查有限性、rho_error≤.005、speed≤.01、mass_offset≤1e-3;每 519 步检查 mass_change≤2e-6、最近最多五采样点质量跨度≤6e-6。任一硬界越界立即停止,保留失败统计及 checkpoint。每采样记录实际质量、u/v 带符号均值、完整场 RMS 差/.002、边界、通量、镜像和非均匀流向;速度稳态不通过可继续到固定上限一次。
原全部 GATES 保留:velocity_change 5e-5(至少8间隔、末4间隔 u/v 同时满足)、mass_change 2e-6、mass_window_span 6e-6、mass_offset 1e-3、rho_error .005、speed .01、zero_speed 2e-6、flux_error .005、flux_span .002、boundary_error 2e-6、top_density_error 5e-7、rho_symmetry 2e-5、velocity_symmetry .002、budget_residual 2e-7,非零内部中心 v 与 A 同号且 max|u|>1e-5。未测/null 不计为通过;不改 gate、不选择偶数 lag。
负例如能运行到上限,在20744保存实际checkpoint,普通路径推进最后16步到20760作参照;独立审计路径加载20744状态,仅推进同一窗口16步,不产生20760之后轨迹。复用已验证 AUDIT 记录真实 incoming/outgoing/collision,覆盖slot/flanks/top;保留临时源码 SHA、逐步真实账及与普通末态 DDF/temp/flags/config/runtime/count 逐值比较。主路径20760步、重叠审计16步分别计数。硬界失败则预算标未测,不继续。
有限幅波动仅报告新轨迹每个519步窗口的在线时间方差 RMS、最大节点峰峰差和场差;不保留逐步全场、不追成因。短恢复/零例也逐步做安全检查。只保留聚合统计、日志和必要小checkpoint。正例只引用既有 J3/lag/offline 结果并明确窗口不同。完成后补一页功能范围/限制/下一里程碑,立即停止。
## 完成摘要:恢复与零例通过,负例速度稳态失败
本轮命令只执行一次,退出码 **1**,来自负例原稳态门槛失败;没有异常、越界或重跑。真实状态短恢复通过;零幅值短例通过。负例达到固定上限,除速度稳态外其余原验收项通过,不能将整体改判通过。正例沿用旧失败。
| 项目 | 实际运行与结果 |
| --- | --- |
| 真实 checkpoint 续跑 | A 从旧 end-21280 恢复并另存,推进16步;关闭A后B从本轮另存文件恢复,推进16步;均到21296 |
| 恢复比较 | 起点及终点 DDF/temp/flags 逐字节一致,step_count/config/runtime 一致;恢复检查通过 |
| 零幅值 | 初始化+64步的65个状态,最大速度严格为0;质量相对跨度/最大偏移6.70552e-8;最大rho偏差7.45058e-8 |
| 负幅值 | 普通路径20760步;独立审计仅重叠20744→20760的16步,未产生20760以后的负例轨迹 |
| 资源/保留 | CPU峰值RSS 211.20 MiB;输出约0.7 MiB;257个旧文件哈希全部保持;未修改生产或旧测试 |
总新执行求解步数为 **20872**:正态恢复两条路径各16步、零例64步、负例普通20760步、独立重叠审计16步;其中正态仅从21280推进至21296,没有正例20760步重放。本次没有测量显存峰值,显存大小在启动前估算并确认有足够余量;不能将估算写成实测。
零例所有逐步数据在 results.json。边界指定速度误差0,顶密度最大误差7.45058e-8≤5e-7,质量跨度低于6e-6、偏移低于1e-3,每步质量变化低于2e-6,零速低于2e-6。相对流量误差/跨度为 null 并明确标 N/A(零参考);没有将其计作通过,也没有声称64步满足至少8间隔的完整稳态要求。零例没有单独的population预算或恢复测试。
### 正负实测与原门槛
正例数值直接引用 j3-reservoir-2026-10-12/results.json,不重新运行;下表为各自20760末态,质量跨度和速度收敛取各自原末四间隔。
| 量 | 原正例 +.002 | 本轮负例 −.002 | 原门槛 / 判定 |
| --- | ---: | ---: | --- |
| u场RMS变化/.002,末4 | 2.6381/2.6857/3.0247/2.9349 e-5 | 4.4394/4.3232/4.4663/4.4558 e-5 | ≤5e-5,均通过 |
| v场RMS变化/.002,末4 | 7.3296/6.9940/6.4742/6.0220 e-5 | 6.0193/6.1294/6.3192/6.4750 e-5 | ≤5e-5,均失败 |
| 初末质量相对偏移 | 1.93463e-7 | 3.08173e-7 | ≤1e-3,通过 |
| 末四间隔质量跨度 | 2.97376e-8 | 3.64015e-8 | ≤6e-6,通过 |
| 末间隔质量相对变化 | 2.17732e-8 | 6.19118e-9 | ≤2e-6,通过 |
| rho最大偏差 | 2.45519e-4 | 2.53472e-4 | ≤.005,通过 |
| 最大速度 | .00198440335 | .00198443044 | ≤.01,通过 |
| 指定边界速度最大误差 | 3.66935e-8 | 3.56677e-8 | ≤2e-6,通过 |
| 顶密度最大误差 | 2.06754e-7 | 1.97440e-7 | ≤5e-7,通过 |
| 截面质量流量相对误差 | .0010008493 | .0007190498 | ≤.005,通过 |
| 截面流量相对跨度 | .0005283367 | .0004005362 | ≤.002,通过 |
| rho镜像误差 | 4.95464e-7 | 6.22123e-7 | ≤2e-5,通过 |
| u/v镜像误差/.002 | .000202076/.000137884 | .000124795/.000216072 | 各≤.002,通过 |
| 内部非均匀流向 | 通过(旧记录) | 中心v=−.001084366,max\|u\|=.000432660 | 中心v与A同号且max\|u\|>1e-5,通过 |
| 初始化边界误差 | 通过(旧记录) | 1.78962e-8 | ≤2e-6,通过 |
| 实际population预算 | 通过(旧末态后16步) | 通过(20744→20760) | 残差/M≤2e-7且逐值一致 |
负例每步有限,逐步观测到的全程最大rho偏差 .000602724、最大速度 .001984436、最大质量偏移8.14183e-7;40个采样间隔的最大质量变化6.43070e-7、最大滚动跨度7.00168e-7,均低于对应硬界。各采样原始值保留,没有删掉早期瞬态。
负例底请求体积流量−.01706689453125;20760末态距底8/16/24处实际质量流量分别−.01706145331、−.01705793291、−.01705461740。顶v范围[−.00045778788,−.00025554935],没有强制等于初始均匀猜测。全域有符号速度均值u=1.29822e-9、v=−.000355422879;末519步有符号空间平均变化分别−1.11917e-10、−5.99107e-9。各y宏观质量/体积流量、顶底所有节点宏观量及每次采样的镜像/流向均保存。
有限幅波动:负例最后 **20242–20760的519帧** 在线时间方差RMS为u=5.06547e-8、v=6.80326e-8;最大节点峰峰差为4.35901e-7、8.38259e-7。旧正例离线窗口为 **20760–21280的521帧**,RMS为3.36455e-8、7.37527e-8(引用旧文件)。时间窗口不同,不能宣称正负同窗口等价;不继续分析成因。
### 重叠16步实际账
临时审计 one_step_double.cu SHA256:`d6532c48ea0bf972bce6ec3809989e9f2ec52eb1440d58f8945eb59d67dcf1b5`。审计与普通末态DDF/temp/flags逐字节相同,配置/运行参数/步数相同。每步 ΔM−实际边界净交换−实际碰撞舍入残差为0,最大相对残差0≤2e-7;未扣舍入的最大相对残差7.51761e-9。
| 16步平均实际量 | incoming | outgoing | 净进入 |
| --- | ---: | ---: | ---: |
| 底slot | 2.65799031034 | 2.67504728318 | −.01705697284 |
| 底flanks | 5.33348024054 | 5.33348734328 | −7.10273e-6 |
| 全顶部 | 8.00853079371 | 7.99147556582 | +.01705522789 |
全边界平均净进入−8.84768e-6,碰撞舍入+8.26980e-6,实际ΔM=−5.77886e-7。预算闭合不代表速度稳态通过,也不等同于宏观截面流量。逐步原始账在results.json。
## 可复核清单与后续边界
唯一新增代码:tests/validation/run_j3_coverage.py;复用旧make_sim/observables/AUDIT及原GATES,未改旧脚本。新脚本SHA256 `329869519b7078e854d96241a7aad8ef93f35ac9be83f0be502c3a93523c3b13`。运行前同一解释器做语法、静止平衡分布宏观量/零参考N/A及状态步数比较的主机检查,均通过,没有初始化CUDA;没有跑无关矩阵。
实际GPU命令(工作目录为 /home/frank14f/CelerisLab):
```bash
env CUDA_VISIBLE_DEVICES=0 PYTHONPATH=/home/frank14f/CelerisLab/src PYTHONDONTWRITEBYTECODE=1 /home/frank14f/anaconda3/envs/pycuda_3_10/bin/python tests/validation/run_j3_coverage.py > research/j3-coverage-2026-10-12/gpu-validation.log 2>&1
```
脚本在创建CUDA上下文前复核GPU0无计算进程、显存小于100 MiB且利用率为0;记录包与kernel实际来源,并核对全部基线哈希。入口拒绝覆盖已有results.json,不能无意重跑。必要checkpoint四个均持久保存,本轮checkpoint路径、SHA及步数在results.json;原始日志、基线清单、独立新增脚本补丁保留,编译目录由现有编译器清理。
**当前功能范围:** 在D2Q9/SRT/FP32/unshifted/double-buffer、无物体/力/LES、固定小网格上,有限平壁slot与顶部reservoir支持正向喷入、负向抽吸和短时零驱动;真实保存/加载后的短续跑一致。正负质量、边界、宏观流量、镜像及population账在上述窗口内通过。
**尚不能保证:** 正负完整速度稳态均失败;未验证长期精度、网格收敛/精度阶、性能、多种碰撞/streaming组合、动态喷口、物体交互、曲面或AMR;零例仅64步,恢复一致只覆盖此次固定配置。量级小不构成精度保证。
**下一真正功能里程碑建议:** 整理一个精简、可外部调用的平壁Jet案例入口,复用现有Simulation及参数,提供正/零/负幅值、喷口宽度和持久恢复用法,明确边界含义并如实显示未收敛状态;不要为此新增求解器抽象或启动AMR重构。这只是建议,本轮不实施。
本轮完成并停止复审,不追加求解或波动诊断。
@@ -0,0 +1,73 @@
M pyproject.toml
M setup.py
M src/CelerisLab/__init__.py
M src/CelerisLab/body/__init__.py
M src/CelerisLab/body/ddf_patch.py
M src/CelerisLab/body/manager.py
M src/CelerisLab/body/preprocess/flag_overlay.py
M src/CelerisLab/common/__init__.py
M src/CelerisLab/common/checkpoint.py
M src/CelerisLab/config.py
M src/CelerisLab/configs/CONFIG.md
M src/CelerisLab/cuda/__init__.py
M src/CelerisLab/cuda/compiler_v2.py
M src/CelerisLab/cuda/context.py
M src/CelerisLab/lbm/__init__.py
M src/CelerisLab/lbm/curved_links.py
M src/CelerisLab/lbm/field.py
M src/CelerisLab/lbm/initializers.py
M src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh
M src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh
M src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh
M src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh
M src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh
M src/CelerisLab/lbm/kernels/config/config_grid.h
M src/CelerisLab/lbm/kernels/config/config_method.h
M src/CelerisLab/lbm/kernels/config/config_objects.h
M src/CelerisLab/lbm/kernels/config/config_physics.h
M src/CelerisLab/lbm/kernels/kernel_v2.cu
M src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh
M src/CelerisLab/lbm/kernels/operators/collision_trt.cuh
M src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh
M src/CelerisLab/lbm/kernels/step/aux_kernels.cu
M src/CelerisLab/lbm/kernels/step/esopull_sync.cu
M src/CelerisLab/lbm/kernels/step/init_flow.cu
M src/CelerisLab/lbm/kernels/step/one_step_double.cu
M src/CelerisLab/lbm/kernels/step/one_step_esopull.cu
M src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh
M src/CelerisLab/lbm/stepper.py
M src/CelerisLab/simulation.py
M tests/integration/test_body_sync_e2e.py
M tests/integration/test_ddf_patch.py
M tests/integration/test_sync_bodies_skeleton.py
M tests/integration/test_unified_obs.py
M tests/postproc/experiment.ipynb
M tests/validation/run_kan99b_rotating_cylinder.py
M tests/validation/run_sah04_st_matrix.py
M tests/validation/test_sensor_accuracy.py
?? docs/design/
?? docs/multilevel_grid_architecture_analysis.md
?? research/
?? src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh
?? "tests/audit/body\345\210\240\345\207\217\345\212\237\350\203\275.md"
?? tests/integration/_cases.py
?? tests/integration/test_numerical_gpu.py
?? tests/integration/test_runtime_contracts_gpu.py
?? tests/integration/test_state_gpu.py
?? tests/unit/cpp/
?? tests/unit/test_build_contracts.py
?? tests/unit/test_context_ownership.py
?? tests/unit/test_initializers.py
?? tests/unit/test_numerical_operators.py
?? tests/unit/test_planar_velocity.py
?? tests/unit/test_reservoir.py
?? tests/unit/test_simulation_lifecycle.py
?? tests/unit/test_slot_velocity.py
?? tests/unit/test_state_regressions.py
?? tests/validation/analyze_j3_saved_frames.py
?? tests/validation/diagnose_j3_lags.py
?? tests/validation/multigrid/
?? tests/validation/run_j1.py
?? tests/validation/run_j2_slot.py
?? tests/validation/run_j3_reservoir.py
?? tests/validation/run_poiseuille.py
@@ -0,0 +1,265 @@
{
"head": "6e3756c587ec08ab6a55c4a1a5f4671822d3f0a0",
"python": "/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python",
"package": "/home/frank14f/CelerisLab/src/CelerisLab/__init__.py",
"cuda_source": "/home/frank14f/CelerisLab/src/CelerisLab/lbm/kernels/kernel_v2.cu",
"hashes": {
".cursor/rules/cuda-style.mdc": "5810cf8cff793a11ba5dedafaa8a4e7d7d3debb728d837ca1903ff6dc8d6fdb9",
".cursor/rules/project-layout.mdc": "aeed1cd9d48447bcfcfb6a77250af7c5a3d500de4c6b2591c5684696fa04c3ec",
".cursor/rules/python-style.mdc": "ece75cb724d7dc46cb8dab7ecf8d710a90b503001da0d506ea4bf772ce395e21",
".cursorignore": "9f072faa815a6c6d4dc791a424201404f0f623338681ae3d2fcbdf86db1bd035",
".gitignore": "de25151f4cfdf29ca64032e509398e1829c7ded2449ccff803b2fd87d859ae6c",
"LICENSE": "e98392425e9a0007d0d69f0f7c912c2dc1b59061a6197223962aac45599c76ea",
"README.md": "982d0df8b766b1d5017ba702b75e8b3cec8d22f57af8f434be27ea251652596c",
"docs/audit/audit_round2.md": "0f14ad073a0725134e6391f961c324fd0013c7791fd410713e94ed1ad40b7385",
"docs/audit/body_refactor_notes.md": "8f978d7b01c9f49dca9eeaff0d163cec6da085e2f99ee5a5e803d72306e7a72f",
"docs/audit/config_diagnosis.md": "b601652df0cac36a8faf2b317b11853221353716a25184cd9b2dc41373a7f183",
"docs/audit/kernel_layer_audit.md": "89893c98ed7c2699157bf728ec0e79b0dd6aff4008ee5c7b77eb052de24033f1",
"docs/design/README.md": "98242c6960866d9b75aaf363f703edf02c4210bc38da1a340e9f6add49c6a3ce",
"docs/design/integrated_architecture.md": "c26b0d301321fe4b86d83d11c7e0b8d0c0545ee2995afa563966f004e9788132",
"docs/design/multi_level_grid_architecture.md": "e56a67d9129f2e3c311342e21a3fb2ed14bd492dd881949b251d5d9ac577bdee",
"docs/design/multi_level_summary.md": "eebf23e0bec9b154e5ce2128e2806e7558a7d4824b2c700cfd16afd1158b2354",
"docs/design/multi_level_visual_reference.md": "cad4bfbd561e5650ec297334529334b662a1ed35f7373c61f34ee22ecf1f66bd",
"docs/design/spatial_coupling_refinement.md": "36c878c7afad524999d89fa842297a98a0433e0283e78b36ca734ddbf8723ed8",
"docs/multilevel_grid_architecture_analysis.md": "90309730b1759d63531cb258c30db990ab71ca1b56ae47d0bbe2f4e2ae52012c",
"docs/performance_analysis.md": "ba01aaa4d3c02b61a8dc55fd00518ac291ebbed79b6574190d6b7234a1158fcb",
"docs/tests_overview.md": "ffc9591fd7baa4261b2c1ce9cfa7aa13a3554a8d5df712035806266a5eaade3f",
"docs/validation_specs/Force_region.md": "3092080afe4a30665fe1b721803621ba9d0dd5d20ad17826984d94efc160fdac",
"docs/validation_specs/Force_region_validation.md": "279a4484d1bfca0fd67aed4de3282d547aa048f89389420d8e5f2fd86db54fc2",
"docs/validation_specs/Kan99b_validation.md": "0d8bf74f2361f863809af1979bf8807adaa423f98321e1104a3d86d8c7a863cf",
"docs/validation_specs/Sah04_validation.md": "1d122d29e281b7f50801b148f3314a0e35fdc27ee7d757c0a661243aa6185fb0",
"docs/validation_specs/exp_ctrl_matrix.md": "b7250576c23292988b6ef4bcfd080f611d41edc413c3cebd0eadcc8596049470",
"docs/validation_specs/streakline_notes.md": "cd342d214c07eb608ac2e5b8697322c44c31dbf4d27dfdb5409de46ef474df4b",
"output/round3_compatibility_summary.md": "319f2e6abde4b34cc4ec90ef461d8ebb85dd5a3ac1736cfa7a3fb110f2a69df9",
"pyproject.toml": "f24ab9ad3a6a728a9382b1bce2e721612fc76635f35c6f96dfddaa853b6e5a9c",
"research/audit-2026-10-09/REVIEW.zh-CN.md": "2841fd3aa7a6baedbe1079d90915c8b05212b133824ed6abccaa1f09656eaefe",
"research/audit-2026-10-09/architecture-cpu-results.json": "e1b809210005c8765b13fddbb5ed710d15f6fcbb4c5788a4064f3e88808433ef",
"research/audit-2026-10-09/architecture-report.md": "861079dc3f4ced9fdc41bfb22002d32e190c0d630d3ba2f138f9dc7a949b8371",
"research/audit-2026-10-09/numerical-report.md": "970330b3a593f79f09866ce6ae82bc0ddd81226230d0a6ff06ae8ae756ee80da",
"research/audit-2026-10-09/numerical_collision_results.json": "51e5c263bb8cde82cedef2ccfdbf5ef657742a80218d7896b1ff877516e59693",
"research/audit-2026-10-09/numerical_compile_results.json": "c3b0ae02072a2ec408ada7513b542ec255f6855cb743a3ed7f91bd8f31504f44",
"research/audit-2026-10-09/numerical_semantics_results.json": "b95b065b594aa2911740dab216f87936c9bf7f7fa25acfda93b5738443564035",
"research/audit-2026-10-09/root-initializers-report.md": "ca448457c444949d5d0e1e10fa7121064510b77fc4c3512580900f0299219867",
"research/audit-2026-10-09/state-report.md": "f8708807efc2e109810c5955f7c1884a932668c0b3cb2963c2df3b09f2a3d5c4",
"research/audit-2026-10-09/state_results.json": "da9170df3e11231c73f20e5e79ed68e08966673d1dd52004ea6b6a279afc0dcd",
"research/design-2026-10-09/Contracts.lean": "2442d9a778ef20e8af3fecf23be6fea6d73c6299ff744c9664b652bc5ee3f034",
"research/design-2026-10-09/PLAN.zh-CN.md": "0341dd7ee306a040340c8e5dedb07a109e931c27dbf3c994d072aa78e3b6bc67",
"research/design-2026-10-09/api-architecture-study.md": "d6fb45ec784f0e1db55fb9f34e137b9f551db0b9b39fd4f0ef247a78fc34eedf",
"research/design-2026-10-09/grid-study.md": "4435dc1275ec5e15b118becc6ac391f306195d1e5beaa58037b1aff3bb2465c7",
"research/design-2026-10-09/jet-study.md": "a362142ef04a5ad5dbb4c9db9d221b1199dccec53780c8f2da49a15201cfe529",
"research/design-2026-10-09/jet_closure_check.py": "fde45d0f8518740ef5c0bf0fe7635d6adaf9a2e789927dd4e68e991c138ddc30",
"research/design-2026-10-09/jet_closure_results.json": "12cf7d400a206f9f9ec9ea6ad251fe6bb0232e27bcbed22fbc1ead2c0fc7d249",
"research/design-2026-10-09/math-and-history.md": "64f8c82e4949d6f58b46faa09800958714859c36cad20bbeeae8b449ae7a6099",
"research/design-2026-10-09/math-checks.json": "94750381954317cde8d649db26beaed8ea945666572a05030ca2b4d97d384011",
"research/design-2026-10-09/math_checks.py": "4254983a783fe4bad8888b3d7c243c87d991c7bbf242edb0f56f25cbaefee890",
"research/j1-2026-10-12/REVIEW.md": "13004a4f140acdcf59acb57e9e2dda1bb95763d30060f822a7c206c94b813a9f",
"research/j1-2026-10-12/baseline-status.txt": "ac398360e05b746b89ae0c3acfe202b5122e650a3bb1ff234ab26f874a303e64",
"research/j1-2026-10-12/baseline.json": "ad7afdf7b3913d11c07343e971fe2f43c2d1a2b99e3d5904a6ba89e3bb0b24fb",
"research/j1-2026-10-12/checkpoint-gpu.log": "adfe3d77d2e6c6f6184dccc0267b4404b20a7709505d5ff5affed0ed4a618083",
"research/j1-2026-10-12/cpu.log": "60cac097f7c4f11401df2aacb43a248640555e7628d2829c4680c71db34e9640",
"research/j1-2026-10-12/gpu-validation.log": "d1e9f2aea17a85eddcd94b81c700738ce073214857b55c28abd1219ff1edbed7",
"research/j1-2026-10-12/gpu.log": "8659a78ea52bbf8eb923d46ea71636ce63cd322352d5c98a74f631e666dd8cfb",
"research/j1-2026-10-12/incremental.diff": "a454c23da7b0011645949c0fbf64d0c41ecfdab5642b1b7c5119868005d3c721",
"research/j1-2026-10-12/results.json": "449f8a17dacac0fc6d2489c4b10bac330dbbbdb38fad3ce54f739ac8c6d48e85",
"research/j2-slot-2026-10-12/REVIEW.md": "10c4a94ffc32e0a2c4e0f6593b7cfc28479b5869f279f0b9d0b708fa3a47d1e6",
"research/j2-slot-2026-10-12/baseline-status.txt": "812616e2d941efcf854e1b37d6e662dda1aaf2b69074fcc04017133e13b72166",
"research/j2-slot-2026-10-12/baseline.json": "e82a1844145fd0cbc585c581b29f80b56193f122cfe1dfa7578f26904a720285",
"research/j2-slot-2026-10-12/cli.log": "9482ad7101d501f27f92e204b2f3ae5c6d91bd887b525aa31cb4a2a188f3cb92",
"research/j2-slot-2026-10-12/cpu.log": "91aba5961006909fbbb860429a9d3cfc930112a0d74c7788bc51c0a5897b47e5",
"research/j2-slot-2026-10-12/gpu-serialization-failure.log": "df804e53b35e7ddaad79a17842b4b5fd9d834e29ca2d56edb00e835848d09200",
"research/j2-slot-2026-10-12/gpu-validation.log": "223351b52c70fa4523289f3a1b3db435a11286379253280470900ffe397580a6",
"research/j2-slot-2026-10-12/incremental.diff": "c9e391bc91438cd912c1ed5a419705d4388522f672c67a066cfc055e814e699f",
"research/j2-slot-2026-10-12/results.json": "7d35ca7989aed5380e0a45de7f583972566fc516a051da63c53b35514e267494",
"research/j3-lag-2026-10-12/REVIEW.md": "f388b64b0cc0413dc9865afda90ed24de666dda0d6cdb821b4363ce1b73631b3",
"research/j3-lag-2026-10-12/baseline-status.txt": "e0b69879084f54afac1a3bc3701f1de9819068190c815ae84421f02f83cad9f7",
"research/j3-lag-2026-10-12/baseline.json": "5e9a920813fe3d775110af85af92970d5245a7040ace804445e432353b77e489",
"research/j3-lag-2026-10-12/end-21280.h5": "19a94e9e8db6dd9ac981effe06032c351992250b58768d9c090409193893d588",
"research/j3-lag-2026-10-12/gpu-availability.log": "b227a519b8286849cfdf842573bd451803da048c6b27af9517f6b8964cd3aa39",
"research/j3-lag-2026-10-12/gpu-diagnostic.log": "97956b517072b7c34e2e29e2a23f87eafb19b9eda786a4b8149e4a2eaed76ee9",
"research/j3-lag-2026-10-12/host-check.log": "b2b6d262934b3abf9e0f0bdbde14b339cb977f7bffe391c17b51b5d067862dda",
"research/j3-lag-2026-10-12/incremental.diff": "ebdf66c72daf17b926482f79a1a30bf0eb2d27fc930a7bb62e5449ebcf72fcc7",
"research/j3-lag-2026-10-12/results.json": "00435ac7e402943e55e702fac1beb5af8cafe71967999658bcde2b29077b1fa8",
"research/j3-lag-2026-10-12/start-20760.h5": "6c4cba5928c77566c2afc32231311a3986831c18fea766faadebb101243399e2",
"research/j3-lag-2026-10-12/trajectory.h5": "2b51f8ec5e0cc8ca72c73ac1b51dd611158368e6d6de791d85150fa111ea1986",
"research/j3-offline-2026-10-12/REVIEW.md": "d9902c58498e73c29e054b23adb968f7e1e14421cba5c58d03bbc5a50159ae79",
"research/j3-offline-2026-10-12/cpu-analysis.log": "bc02a9b197fc15ae1b503ca54655a7622d4361f9b45b7848ff9c387ea3665f11",
"research/j3-offline-2026-10-12/lags.csv": "fbd9addd413f24c47f4411317e872265bb774e8e1724fe169412befa860ae94d",
"research/j3-offline-2026-10-12/localization.png": "a72907638e32b0ecfc2205bea438e7b408f40aad86217ce6ad9b4877840c9cfc",
"research/j3-offline-2026-10-12/regions.csv": "3a8fc640b61d70e3b7f73d2bf8ac2bd3f720adf39a90dfda6180430e0489efae",
"research/j3-offline-2026-10-12/results.json": "cdb857bea6f4e06ed15acf773505ce6d5147f8cb8ce0a53cc368ee267cde6361",
"research/j3-reservoir-2026-10-12/REVIEW.md": "1ea5f860728584ea6cbe40ba3994e40471102d8e2cf6d93e28fe47222cba0cab",
"research/j3-reservoir-2026-10-12/baseline-status.txt": "0ef1a8c9878c4053ebc1a7d4bace6d4ec38bf27ace167b4239ddbb1c6c897e20",
"research/j3-reservoir-2026-10-12/baseline.json": "847fefd1eae971985d34d04d89ee6d6f1c91f6940c54fe351d112faba7bc6838",
"research/j3-reservoir-2026-10-12/cpu.log": "b33f6c1a1b0ee67968c4cff85d491e46e30e0d6c796b552629714ab8b5dcead0",
"research/j3-reservoir-2026-10-12/gpu-availability-sandbox.log": "1d58470512e583a0acfabf6896ee5f31e5b493b8231aed54b864f64eb275b02c",
"research/j3-reservoir-2026-10-12/gpu-validation.log": "ff04024db197e332f37c912a96413e3251fd0186947348ffbc33af6f4a899f2c",
"research/j3-reservoir-2026-10-12/incremental.diff": "fae312831d71e46dd477a640b06ed927853a9e735d26bf9f5868927fa31cfa56",
"research/j3-reservoir-2026-10-12/results.json": "49685de7679a14860258abf1753aaa6d116ad709b868d907ddb40e74c9b845ea",
"research/repair-2026-10-10/TRON_HANDOFF.md": "f8aaa3d99cd133c2055d4adf396a0a57d14f6006aea19e87611bd1c2c1b53a88",
"research/repair-2026-10-10/baseline-hashes.json": "d6a7d5f9ec5bceb0e7927d55603d9c5e70105982cd945723454659b19ab476e6",
"research/repair-2026-10-10/baseline-status.txt": "074088d793014e3b8154c58718058c7d300fb45595f5129fa957ef1e4cec38e2",
"research/repair-2026-10-10/checkpoint-domain-2026-10-12.diff": "292b4bafe7a62d4fbbf7c165eb99929336edfcaa16b15f34f72ab71fcd928391",
"research/repair-2026-10-10/classic-results.json": "a5d15305f516fd378b54cf9029102be58a83a55a7bad4b8e058fcfe0cc9898f4",
"research/repair-2026-10-10/classic-signals.npz": "820c9a0b0713d7455f0a5839ac2cd5ee706086d1a26461225dcdb095673421e2",
"research/repair-2026-10-10/final-gpu.log": "988bb97256d17b88c14f3793b15880d727ecb285abe62e7d2ae27a16729651c3",
"research/repair-2026-10-10/final-unit.log": "a892a39ecf88125558538cadce2cb5dc46d106b993b164e03da4ebb0eee68cef",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_grid.h": "8be3a7cf74ba30d7fd3074fed79e63dbda7311c4d03b454ea641bf298ffeaa8d",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_method.h": "3db4e16ef2c6b22349d04e6aa8ab04bdfe0eb784f9f3a98277e15dbed1835d81",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_objects.h": "dbb93c063586da278c15d95e23f84c12e728f4f5f1bbc3980fe9cedaa6fff90e",
"research/repair-2026-10-10/original-user-files/src/CelerisLab/lbm/kernels/config/config_physics.h": "26df33c2960ba36f3283e19b55b4ea92e50e4efda705f9ebfbf3f875a4092c59",
"research/repair-2026-10-10/original-user-files/tests/postproc/experiment.ipynb": "c6b45db1c57200f0777213ef8d44cb4996c1aa7a5fb42b968b77e56f51b4fca4",
"research/repair-2026-10-10/provenance.json": "a81b7e32ecf7182c9617df1b39bbb063a05ef89290ad501bac4573cd5e8a6832",
"research/repair-2026-10-10/repair-architecture.md": "49be42ff5c994017f3175e17efda14d84f0b68f8ecd239f66ccee38415b60c5a",
"research/repair-2026-10-10/repair-numerical.md": "0272ebfa8c519aad161c520542cf53156574661609b91fd5ccad7955fdf2bd7b",
"research/repair-2026-10-10/repair-state.md": "4d4aa1ec0c11a87d2c8380912e7ed74cf5c910ae42e5cc529effde36c9020969",
"research/repair-2026-10-10/simplification-checks.log": "c9f15e870d02003480adf1a7f2fe4a9aca66c1934c4477619f05c8a4798ba85b",
"setup.py": "bf07df7ec19de56710d2bb5f61873e09710cd059d46837dc3aa54f3e09ff9e06",
"src/CelerisLab/__init__.py": "21cc469bd6e970a1f9ff5970c8eea4602065e41fc881854759ee565ee55c10c6",
"src/CelerisLab/body/__init__.py": "d6ec221d51eaf7b1da11ef320b399599cf5b9422e5bc271a7264a273033e6928",
"src/CelerisLab/body/action_smoother.py": "b1a23ee6bbd4850b172cb8738c5c3546ee465a54189e6af9d8044f023d4687dc",
"src/CelerisLab/body/coupling/__init__.py": "c931f7eb318d48408c3e2febcc6917c88c8dcc1697cbf4329b1f340d94c35763",
"src/CelerisLab/body/coupling/soa_packer.py": "8ec26fd55ef74801bbd5ab6bd3d0a7dabc750cbd498aaac2ca4c61a0108ad3c9",
"src/CelerisLab/body/ddf_patch.py": "60fcfb7441e73bf290bcff41ca3a83da3e7ddad765d7247464e8f02e3043b4e2",
"src/CelerisLab/body/geometry/__init__.py": "ada88980ab672959aca9aa3a4c4aade3219524b2ab68110cd2a2f41e3e0ca90a",
"src/CelerisLab/body/geometry/base.py": "cceca14361ca2f34d34a3e43730e1a79b8ca81be00f0dd62e884db32b479419f",
"src/CelerisLab/body/geometry/circle.py": "7605ca7c21103f1d801ac73ab8dd18dffbdac425b2dee7b8858b283628a9e436",
"src/CelerisLab/body/manager.py": "eac22c9ac92c26e89c10bb089fb3c4156e4eb7bd0c1b1f6fe6dd32e2940a020e",
"src/CelerisLab/body/objects.py": "71692d098ebb5ab2d0e614cb9b7854f048b8b33fbe6707e61fd0e8ac35745017",
"src/CelerisLab/body/preprocess/__init__.py": "dfd9d58bc07f626ab23a70053e31b88a6d9165d2e4c76a4e9f48abe674d3d2ec",
"src/CelerisLab/body/preprocess/flag_overlay.py": "831fc9e9736b758847759a085ff133eb49ec91318ace4fda76f85960138ee300",
"src/CelerisLab/body/registry.py": "fbb7327780adbdc6da15ebdb799980daf32df22ee974af0893d7409f177bbb68",
"src/CelerisLab/body/sync_plan.py": "a73ac9ee361b2120d0b7bbebeaa2ccbf924ba27bd95d4dd4b383c10a39b2a409",
"src/CelerisLab/common/__init__.py": "d4dbde78bc97fccc9eabac9abae8f0f15c112c10ff8e9b45bd9401d4723df1ef",
"src/CelerisLab/common/_types.py": "aad2ff1a9033d4fd68783ad7123afb47201ddc58785cb6dc0246947037072a5f",
"src/CelerisLab/common/checkpoint.py": "5b7caf3896167a3f37c539b58837de6eb3f8085fa7bf5f821a09666cc16d43a4",
"src/CelerisLab/common/pathline.py": "a1b6efcc0a076d0f1dc8d49a595779426d7d5626b00072a59bac710ff02ad046",
"src/CelerisLab/common/preprocess.py": "7fc78a08857cf8e98519500b094a1d896af189b6b15658ff9b388ed51bed4515",
"src/CelerisLab/common/render.py": "0e055476257eb2bcd11e733766e52195de02f8fad228f570a3511a7c831bdc29",
"src/CelerisLab/common/streakline/__init__.py": "13ff1cfa416fdd721a08a659e76b5a5a99b8d3201add10a83b7b0bc654bc1eec",
"src/CelerisLab/common/streakline/_config.py": "a9185ef68e9c7b5d5a1dc0b04a28341e2ad91d13c145a7c106636a878cf0a605",
"src/CelerisLab/common/streakline/_integrate.py": "3fbd4368b2c8d0e7fda40dc65aac5df02b085008b4c68acd83cb7ae45d33a13b",
"src/CelerisLab/common/streakline/_render.py": "236cd637414ee318c4d66f9aed32110d8dc42a100d65fde06172f7cd0ba62c65",
"src/CelerisLab/common/streakline/_streakline.py": "1a3e08daa706b5f83cdeb337e9a945a36ddf7583c40af1d0bb9d825ac954df37",
"src/CelerisLab/config.py": "2f1bba7515f5bc08cb3a8d140bcafe7fa0689e01b3b06494697bb2956a71530e",
"src/CelerisLab/configs/CONFIG.md": "41cafdbe525366c08aa9d0416ea026ccf0026ba7123b8a9b65f968a80d928e3a",
"src/CelerisLab/configs/config_body.json": "055f261f0828ca1d4f2bb694bd15b72bbcabe31d552326208f28e37f761adab1",
"src/CelerisLab/configs/config_lbm.json": "17e4311f1f250c6ece59177a8b6ff856b69a016c7c10267e774b030a0a390865",
"src/CelerisLab/configs/config_lbm_flume_mrt_zouhe.json": "8f593321db05a563a42931603a228d61cbcba06dfbe113262d5cd0ad93c0fe79",
"src/CelerisLab/configs/config_lbm_flume_trt_regularized.json": "f4bba8e6a4339fc3c4eb14f6e2f57c4b22993c73703c773d853edfbe34736e56",
"src/CelerisLab/configs/config_lbm_three_cylinder_triangle.json": "eeb8e7149dbe4aa6b3a9562802735aa950750dfbe2d972a0727e788573afa817",
"src/CelerisLab/cuda/__init__.py": "0d01dff9f0399c8baba822aab5ca0122a135f011008ed8a499ebd9f7e5b06aea",
"src/CelerisLab/cuda/compiler_v2.py": "c4cc3ec4445c8d75e6a253dd87963877117a722bc73b9d4811806fc6045d08c1",
"src/CelerisLab/cuda/context.py": "013dd4ec6d01d2fbd11afdfb103eac6a273bd9f798d663d761b851eeb27885e9",
"src/CelerisLab/cuda/obs_layout.py": "5ffb2c3aeeaaaaeb64f2cd8febfbcf4ad9919e5414020ad753cfade0683b21c2",
"src/CelerisLab/lbm/__init__.py": "7f60fb3aaae81501b510d08c2fedff44fcb05657260eb10b6f5cc91e7204306b",
"src/CelerisLab/lbm/curved_links.py": "587f3f4638688c09c0850bef2f314780d03f06c9211abc5fd773fbeecabc3326",
"src/CelerisLab/lbm/descriptors.py": "c9f025dfc14da43b989047b84cc22bd05d5cc92c9ec695c1da68fdfb788e3f2b",
"src/CelerisLab/lbm/equilibrium.py": "2fb2f2bb7ff326d23abce80fc2a4c0907b17740ea3e29fe6ae079c5044783826",
"src/CelerisLab/lbm/field.py": "0e727eacc3706add4d8d15c418e9b631050871f831698d3ac689dd5f2c701b9b",
"src/CelerisLab/lbm/initializers.py": "dacf9586963e862d6d0a98ef1a066036be6f91e9d423720661d8ef2c1fb2df6a",
"src/CelerisLab/lbm/kernels/boundary/bounce_back.cuh": "aba3748c564ed91b161d268ef8b737b7c7be96a823063d201f3da684dd845233",
"src/CelerisLab/lbm/kernels/boundary/curved_boundary.cuh": "4bd761e81b32f4bb3238fbb1f6ea890cde0cc987cd8bbeb54e9df8b0e1b57914",
"src/CelerisLab/lbm/kernels/boundary/esopull_curved_helpers.cuh": "b9b474bc4edaff05681c5443235472d04072d0d775fc0eb9c5967faef52b0258",
"src/CelerisLab/lbm/kernels/boundary/ibm_kernels.cuh": "e6909b547dc8d64cdd8a76a90660243a8f5fee535caa161b52b4dd8b7c29934b",
"src/CelerisLab/lbm/kernels/boundary/inlet/channel_stabilized.cuh": "efe077afcbb6b731256a987c2fd79a1dbc470c902f87070d60421ea6cb13d4e2",
"src/CelerisLab/lbm/kernels/boundary/inlet/common.cuh": "f3cec54c8873c65b3dca4375605d2c89a8727765884d3954c235242fdff9c6ba",
"src/CelerisLab/lbm/kernels/boundary/inlet/equilibrium.cuh": "f0964c811b2c41a5aaa1c6d99c490b06e850c634eb8749f1f05ef61f93c2de1d",
"src/CelerisLab/lbm/kernels/boundary/inlet/regularized.cuh": "943d4a571818bacb89c70bccfaac202691121e3e385803ce6309123a0a03ddaf",
"src/CelerisLab/lbm/kernels/boundary/inlet/zou_he_local.cuh": "e73e66b853b1e4e0e30d8f4185d832aa414ce670a1813ce2b5459f2887f71f89",
"src/CelerisLab/lbm/kernels/boundary/inlet_outlet.cuh": "de8b213a6da42c2e5e9f8966199fc66ea4541b85144a90f3f5dbad3c6ab63b97",
"src/CelerisLab/lbm/kernels/boundary/outlet/pressure_neq.cuh": "c8b2adc66d12fe602076ddc9693c5c208711fcaddb58aa9a31401a269f51c4c4",
"src/CelerisLab/lbm/kernels/boundary/planar_velocity.cuh": "0b2f9e0bd483c199637e5672dc0ffc460bc383dd1804805befbeb4c5d8c708d1",
"src/CelerisLab/lbm/kernels/config.h": "7d1124125e0b354558297934460e64c760fb68cdd7bf6d01a1238bb2eaab8c37",
"src/CelerisLab/lbm/kernels/config/config_grid.h": "8be3a7cf74ba30d7fd3074fed79e63dbda7311c4d03b454ea641bf298ffeaa8d",
"src/CelerisLab/lbm/kernels/config/config_method.h": "3db4e16ef2c6b22349d04e6aa8ab04bdfe0eb784f9f3a98277e15dbed1835d81",
"src/CelerisLab/lbm/kernels/config/config_objects.h": "dbb93c063586da278c15d95e23f84c12e728f4f5f1bbc3980fe9cedaa6fff90e",
"src/CelerisLab/lbm/kernels/config/config_obs.h": "c11e2249359145b5c4cbaaf0487506fa77c1f4b82c7c169ddc574aa0babcd727",
"src/CelerisLab/lbm/kernels/config/config_physics.h": "26df33c2960ba36f3283e19b55b4ea92e50e4efda705f9ebfbf3f875a4092c59",
"src/CelerisLab/lbm/kernels/core/descriptors.cuh": "8440bc14857da9007982650f828a23608eec9f7cc4bf772e8c8dc1239cb45356",
"src/CelerisLab/lbm/kernels/core/flags.cuh": "0025705f24710330d9d9195f713879bfb650a85a3449baef0e196b831af104ab",
"src/CelerisLab/lbm/kernels/core/layout.cuh": "1fbd820021c89ac3efcde24145996cb0147769e607e498e61f308ed3e0b13706",
"src/CelerisLab/lbm/kernels/core/obs.cuh": "b742b77c9f61e1f020fe9922c3838ae9d855e17b381154958b58f10a22938922",
"src/CelerisLab/lbm/kernels/core/params.cuh": "6e18bf730d936d940e3d85452f0714a2eaae31bf41002f9fd520ec5b372878dd",
"src/CelerisLab/lbm/kernels/core/precision.cuh": "849df14b4cce50af52399e4b8f3e997196f3ae5f1163f68e28df3e6b2507a8c4",
"src/CelerisLab/lbm/kernels/kernel_v2.cu": "c7bd3fb705b77261ba2441c52a24a7e6a7865c165cba088a1b75201c4d29c408",
"src/CelerisLab/lbm/kernels/operators/collision_mrt.cuh": "aee444eb60c47a3fd518dca975d1af05425a0818a0ec6c3fb3f6150f60c2cb44",
"src/CelerisLab/lbm/kernels/operators/collision_srt.cuh": "6b7ff842f392c8f853d2d1a97cc69bfe50f21283f73e659404da07cf6c95f5e1",
"src/CelerisLab/lbm/kernels/operators/collision_trt.cuh": "9725b9840b9ad8b4ec7be61ff5d06d3151e86d1a87585c13f2fbf934d0d2c5f6",
"src/CelerisLab/lbm/kernels/operators/forcing_guo.cuh": "969a430c1af03f32e3bd0df95d805e64f56334717c44dd4ba208ba503062a24b",
"src/CelerisLab/lbm/kernels/operators/helpers.cuh": "0b3a4d95d7d19f5fec09e5423b8f4cc99f8a226b541967425967330da5a051ec",
"src/CelerisLab/lbm/kernels/operators/macro.cuh": "e27c1c410dc857be98da4596568e405eeaf88701d291ac0e398aa9cd23dee740",
"src/CelerisLab/lbm/kernels/operators/turbulence_smag.cuh": "ff7f000297ee0817e255ad9fcb6a13b647e3ddd5b206518d35f38d2895a9f501",
"src/CelerisLab/lbm/kernels/step/aux_kernels.cu": "bb7f07d898f0d5151e5bd0f45e6bd819c5e83a345a265b73204906ac3cc29db4",
"src/CelerisLab/lbm/kernels/step/esopull_macro.cu": "c73116020ca217ede1e4de27c8269c31f9d91e33433ac8252a21e9b14187c50f",
"src/CelerisLab/lbm/kernels/step/esopull_sync.cu": "c0ff3e72900c3ab89a05dd03684e96d3b740cf1672d565727fc2af165933d087",
"src/CelerisLab/lbm/kernels/step/init_flow.cu": "305be3bb12fc0d039acec1701baabcf0e8a35e683c49c34f2af8ca9867d2b29c",
"src/CelerisLab/lbm/kernels/step/one_step_double.cu": "f9f8242b38e8e0cf8425b75e2b0215bc15363c62eaa0fb43c761b8e0931bfdc9",
"src/CelerisLab/lbm/kernels/step/one_step_esopull.cu": "aa223b2744ae6c9125673df311a96ce588032c1ba58bebb11fd33ecb990f8ed4",
"src/CelerisLab/lbm/kernels/streaming/esopull_semantic_helpers.cuh": "dd5a9091628b079efd97e53fd49e52d09dcee88529235db77a5648e02937af6e",
"src/CelerisLab/lbm/kernels/streaming/esopull_single_buffer.cuh": "77ed4ab9a0ebc5ff62a91a7c39066ef395391ae36e9040a69fb2bd8b1626dc79",
"src/CelerisLab/lbm/kernels/streaming/pull_double_buffer.cuh": "b65d741ed78b7b62f99531ba0c0ce1936663d8dc9640e7d7d16c707f1baf6549",
"src/CelerisLab/lbm/stepper.py": "e9e51e3a902fbda086d4707c0487e7b1dea6246fab290a24d82bd52d4296410e",
"src/CelerisLab/simulation.py": "34d69e71844f553790c5a2bed0f8fbfb912a9498e95b500d1ef2ad41cae3b424",
"tests/audit/Force_region.md": "3092080afe4a30665fe1b721803621ba9d0dd5d20ad17826984d94efc160fdac",
"tests/audit/Force_region_validation.md": "279a4484d1bfca0fd67aed4de3282d547aa048f89389420d8e5f2fd86db54fc2",
"tests/audit/body\u5220\u51cf\u529f\u80fd.md": "e9f308a8cd0f0e7df5441c32a15f84c0bae50bc0e56b8728f6c6f2cf78596673",
"tests/audit/body\u91cd\u6784\u7b14\u8bb0.md": "8f978d7b01c9f49dca9eeaff0d163cec6da085e2f99ee5a5e803d72306e7a72f",
"tests/audit/\u517c\u5bb9\u6027\u6d4b\u8bd5.md": "9c1721a33b381b9c3810545772b022913da06617711b5ba13a3c2c991b81a7f7",
"tests/audit/\u5ba1\u8ba1.md": "0f14ad073a0725134e6391f961c324fd0013c7791fd410713e94ed1ad40b7385",
"tests/audit/\u5ba1\u8ba1\u62a5\u544a_kernel_layer.md": "89893c98ed7c2699157bf728ec0e79b0dd6aff4008ee5c7b77eb052de24033f1",
"tests/conftest.py": "fa0ec26667872c9c1011d608310d2551fd24719b5d216f06d923ff4c74c73237",
"tests/integration/__init__.py": "c354e43ba09b55a8013a2df2069438740b5f48b5917d855e52e33ab5d7da5a6c",
"tests/integration/_cases.py": "ab76ca1096d2d10fb05b3539aa8ed3c7e549619bae6900ac98723f6c3c908f2d",
"tests/integration/test_body_sync_e2e.py": "d29f01771f3512a4b3ad06fae4ee952327d7fd9f0476942402fe92e9e327fcec",
"tests/integration/test_ddf_patch.py": "dda2abba32ca13e17098232f2831a0b1b66439c35f8931d9997a0257250c1281",
"tests/integration/test_numerical_gpu.py": "002a6745929bd5ee86a9491ea9bc3f97602fb825ea17262ea190c9311881100e",
"tests/integration/test_runtime_contracts_gpu.py": "775e578e2e8072af32fc740b2698abbb79454235a0f3ee929ac4c75d747f8db5",
"tests/integration/test_state_gpu.py": "dde0948941e8abbc5ea10a3acb3a35abbaea576f36ecee0f1120fbcf7454d60b",
"tests/integration/test_sync_bodies_skeleton.py": "65f55a0980659b49ae0027f0642a27e2ebaead226ef083f233e878150884b07c",
"tests/integration/test_unified_obs.py": "4a681536099741d92bdc258525fe3374cbdbeba0d49996e53808381a1b6a13fa",
"tests/postproc/experiment.ipynb": "c6b45db1c57200f0777213ef8d44cb4996c1aa7a5fb42b968b77e56f51b4fca4",
"tests/postproc/run_exp_ctrl_matrix_streakline.py": "529d5f31a3862080f890c65177502b589710b2d960ddf131abaf7dc2f9e2a96f",
"tests/postproc/run_exp_ctrl_matrix_vorticity.py": "b7e0c4113111b9b677f321750c0055656ccfa4f45c25fe7846f3ed22f30d1467",
"tests/postproc/run_kan99b_streakline.py": "a2bbf3fc629ea170d2d4879317dbf2b81c43378a328100ac1f2ee8d9895666cb",
"tests/postproc/run_stealth_steady_sweep.py": "3c32c4dede7da77fd6cfbd3f7b1ff43bb11390aaba621883ec96c6c7fdad5af7",
"tests/postproc/streakline_triangle_clean.png": "aa6669de7af6f82e98af25698a15f494e9cea20cb911ad9a30fe52597d33bb79",
"tests/postproc/vorticity_triangle_clean.png": "f831b8143b50f038d5920a0658469622655f34176d30cf7216feff108aa2ecaf",
"tests/screening/run_config_sweep.py": "5030c99923815ed6ad39110cb56f748c579ff4c66c7c1a368ad1a6008017e2ff",
"tests/specs/Kan99b_validation.md": "0d8bf74f2361f863809af1979bf8807adaa423f98321e1104a3d86d8c7a863cf",
"tests/specs/Sah04_validation.md": "1d122d29e281b7f50801b148f3314a0e35fdc27ee7d757c0a661243aa6185fb0",
"tests/specs/exp_ctrl_matrix.md": "5d9dd2e703582572eb68afe3a7096ea43ec82aa03418d20ed283c5365031e433",
"tests/specs/kan99b.md": "b7e0669f0a6b677d902204f3427d1b3ac254bfe70c37d9cf995fb3e8f1fedfb1",
"tests/specs/sah04.md": "33dbe5e0fd63738abd055c4aa403c191b6de04e6efdbc568f1942c6d23c7459f",
"tests/specs/streakline_notes.md": "cd342d214c07eb608ac2e5b8697322c44c31dbf4d27dfdb5409de46ef474df4b",
"tests/unit/__init__.py": "17f57920d9c1ff46096ceb2af008eb38c4b98dc81ffa3c3d310e758e80ca1cd4",
"tests/unit/cpp/collision_regression.cpp": "f17acdff74ab82a62dc5402b42e3f6a149c262e89b140494164d6ebd630f5e14",
"tests/unit/cpp/planar_velocity.cpp": "8dea266984edc69d4e0e68007e038d7a587e99f84e33478d6656a66a56680933",
"tests/unit/cpp/reservoir.cpp": "c3eacaf0271400eb45ad559b571a8f7faa2a809d5f1857ffeb5592addce2cd0c",
"tests/unit/cpp/semantic_regression.cpp": "99dba074c0c0a32ea76026e7d54fc60af8e6d3dc5315c8900c470b4518878f39",
"tests/unit/cpp/slot_profile.cpp": "31ac58ccab175bf79fa59fc46d4c0842df18ab0a5e5916be84760d9da2b75788",
"tests/unit/test_body_flags.py": "ac6409157924e15a13a3d2cc2f1a09014b8b0198ba17c824f412ff20b19e2aac",
"tests/unit/test_build_contracts.py": "7bb237425e8bb481f312fa4841c484e280731e13c7cbb9a53dad3e7f98984ac3",
"tests/unit/test_context_ownership.py": "299fed30dd0f9bd4dadd8b27f50df2a6367bdb0ab2ca3f391f215fde7241f35a",
"tests/unit/test_equilibrium.py": "1ecbcc4547b1c846b75320463d828d6a36b6aae73208084fae476b1001c1bb50",
"tests/unit/test_initializers.py": "8b4e3358d925614984265ae73c142006b48fd1c3918cf84901f18afd9fe68c3a",
"tests/unit/test_numerical_operators.py": "6d1d560ef553a2af7adac7db3e325d96d7fe39073d5fe3e0e982439537385b27",
"tests/unit/test_pending_edits.py": "905a0dff23b123e8e38aaf364984c810fe51c39acd64aa271e343a4701d3d024",
"tests/unit/test_planar_velocity.py": "b656da0880b4234b1db805544edbe0d2473cbcc7c2c869c71d8251337f62a982",
"tests/unit/test_reservoir.py": "e718c78a53c3941aba7feb8ae4e8bb0b1726c1145de84febf91220c1917991c9",
"tests/unit/test_simulation_lifecycle.py": "77abdc33218c35e9c8b62dbd99ceddbaccd8417e7f0b539ea8859ea0175c663a",
"tests/unit/test_slot_velocity.py": "6a9494de9a32c350389ccbed58af48951f6b25a21a258537d2e8b73eb67cb11d",
"tests/unit/test_state_regressions.py": "0f69cfeb83428192f95688c76abcae7e5b9cf5f27c52bca4ac20c7f320044374",
"tests/unit/test_sync_plan.py": "983313ef783143231fa5a392f85f3bac011184773ccaf5d946504c206cabb721",
"tests/validation/analyze_j3_saved_frames.py": "438f67dac682b94c4950626f8de4fdcde48c3a4e9ecf8fdf1b0ada4b6e0e781a",
"tests/validation/diagnose_j3_lags.py": "286fcd65b3261667a847b9b26e213d0af92cf459faa6bbd774f78c8479ce31d7",
"tests/validation/multigrid/MULTIGRID_VERIFICATION_STRATEGY.md": "d4f3473da44abee6031a0e1bd4d0ca589077a18f15d2461836e4d2ebb98e458a",
"tests/validation/run_j1.py": "51b758a271ff358f931b3140a80082294a67e66c2fec0f8c19319e37f92aadc4",
"tests/validation/run_j2_slot.py": "b7d2d3aa06fcafc3ac62ed4a50892afbdb7f86e5720ce75a39ce317b6f571dad",
"tests/validation/run_j3_reservoir.py": "47535bc3569ce68c888d38978bc4f9077fd763a17829c20c081be52bb18a2903",
"tests/validation/run_kan99b_rotating_cylinder.py": "323186429a100f36b41ab9b81ade2da6a47e93be3ccb7034a3a6b97f4ee8eb00",
"tests/validation/run_perf_baseline.py": "93dde2eb1132f45ea69e1e285ff421dc97a83651a22c79571f299c1909650721",
"tests/validation/run_poiseuille.py": "e529288e2ffa8e00d281a9006723954d60a96ae4d025e8f28656c09287d4ff46",
"tests/validation/run_sah04_st_matrix.py": "9b9c0ce063e07a316846635ee769b837ed26be6bf039f78f4219c10b516f8006",
"tests/validation/test_sensor_accuracy.py": "c6038a9e7a597a1738814bd15e6ecf357cfd271cdc2a132d47943c5280ac0ef9"
}
}
@@ -0,0 +1,348 @@
diff --git a/tests/validation/run_j3_coverage.py b/tests/validation/run_j3_coverage.py
new file mode 100644
index 0000000..d66c299
--- /dev/null
+++ b/tests/validation/run_j3_coverage.py
@@ -0,0 +1,342 @@
+"""One bounded J3 restart/zero/negative run; frozen plan in research/j3-coverage-2026-10-12."""
+from dataclasses import asdict
+import hashlib
+import json
+import os
+from pathlib import Path
+import resource
+import subprocess
+import sys
+import traceback
+
+import h5py
+import numpy as np
+import pycuda.driver as cuda
+import CelerisLab
+from CelerisLab.cuda import compiler_v2 as compiler
+from run_j1 import ROOT, AUDIT, make_sim, populations, observables
+from run_j2_slot import GATES, targets
+
+OUT = ROOT/'research/j3-coverage-2026-10-12'
+SOURCE = ROOT/'research/j3-lag-2026-10-12/end-21280.h5'
+SOURCE_SHA = '19a94e9e8db6dd9ac981effe06032c351992250b58768d9c090409193893d588'
+SCALE, CHUNK, LIMIT = .002, 519, 20760
+
+
+def sha(path):
+ digest = hashlib.sha256()
+ with Path(path).open('rb') as stream:
+ for chunk in iter(lambda: stream.read(1024*1024), b''):
+ digest.update(chunk)
+ return digest.hexdigest()
+
+
+def create(amplitude):
+ return make_sim(amplitude, nx=48, top_u=0., slot_width=16, top_mode='reservoir')
+
+
+def state(sim):
+ arrays = dict(ddf=np.empty(sim.field.n*9, dtype=np.float32),
+ temp=np.empty(sim.field.n*9, dtype=np.float32),
+ flag=np.empty(sim.field.n, dtype=np.uint16))
+ with sim.ctx.activate():
+ for name, array in arrays.items():
+ cuda.memcpy_dtoh(array, getattr(sim.field, name+'_gpu'))
+ return dict(arrays=arrays, step=sim.stepper.step_count,
+ config=asdict(sim.lbm_cfg), runtime=sim.field._runtime_params.copy())
+
+
+def compare(a, b):
+ checks = {name: a['arrays'][name].tobytes() == b['arrays'][name].tobytes()
+ for name in a['arrays']}
+ checks.update({name: a[name] == b[name] for name in ('step', 'config', 'runtime')})
+ return checks
+
+
+def persist(sim, name):
+ path = OUT/name
+ assert not path.exists(), path
+ sim.save_checkpoint(str(path))
+ return dict(path=str(path), sha256=sha(path), step=sim.stepper.step_count)
+
+
+def measure(f, amplitude, initial_mass, previous=None):
+ rho, u, v = observables(f)
+ bottom, top, _ = targets(amplitude)
+ mass = float(rho.sum())
+ flux = (rho*v).sum(axis=1)
+ reference = float(rho.mean()*bottom.sum())
+ row = dict(mass=mass, mass_offset=abs(mass-initial_mass)/initial_mass,
+ rho_range=[float(rho.min()), float(rho.max())], rho_error=float(np.abs(rho-1).max()),
+ max_speed=float(np.hypot(u, v).max()), u_mean=float(u.mean()), v_mean=float(v.mean()),
+ boundary_error=float(max(np.abs(v[0]-bottom).max(), np.abs(u[[0, -1]]).max())),
+ top_density_error=float(np.abs(rho[-1]-1).max()),
+ top_velocity_range=[float(v[-1].min()), float(v[-1].max())],
+ mass_flux_by_y=flux.tolist(), volume_flux_by_y=v.sum(axis=1).tolist(),
+ flux_error=float(np.max(np.abs(flux[[8, 16, 24]]-reference))/abs(reference)) if amplitude else None,
+ flux_span=float(np.ptp(flux[[8, 16, 24]])/abs(reference)) if amplitude else None,
+ symmetry=dict(rho=float(np.max(np.abs(rho-rho[:, ::-1]))),
+ u=float(np.max(np.abs(u+u[:, ::-1]))/SCALE),
+ v=float(np.max(np.abs(v-v[:, ::-1]))/SCALE)),
+ center_v=float(v[8, 24]), max_abs_u=float(np.abs(u).max()),
+ nonuniform=bool(v[8, 24]*amplitude > 0 and np.abs(u).max() > 1e-5) if amplitude else None,
+ finite=bool(np.isfinite(f).all() and np.isfinite(rho).all() and
+ np.isfinite(u).all() and np.isfinite(v).all()))
+ if previous is not None:
+ row.update(u_change=float(np.sqrt(np.mean((u-previous[0])**2))/SCALE),
+ v_change=float(np.sqrt(np.mean((v-previous[1])**2))/SCALE),
+ u_signed_change=float((u-previous[0]).mean()),
+ v_signed_change=float((v-previous[1]).mean()))
+ return row, (rho, u, v)
+
+
+def check_step(sim, mass0, extrema):
+ f = populations(sim)
+ rho, u, v = observables(f)
+ values = dict(rho_error=float(np.abs(rho-1).max()), speed=float(np.hypot(u, v).max()),
+ mass_offset=abs(float(rho.sum())-mass0)/mass0)
+ finite = bool(np.isfinite(f).all() and all(np.isfinite(a).all() for a in (rho, u, v)))
+ for key, value in values.items():
+ extrema[key] = max(extrema.get(key, 0.), value)
+ if not finite or any(value > GATES[key] for key, value in values.items()):
+ raise RuntimeError(f'Hard stop at step {sim.stepper.step_count}: finite={finite}, {values}')
+ return f, (rho, u, v)
+
+
+def restart(report, save):
+ with h5py.File(SOURCE, 'r') as hf:
+ assert int(hf.attrs['step_count']) == 21280
+ assert str(hf.attrs['distribution_phase']).startswith('postcollision g(t)')
+ config, runtime = json.loads(hf.attrs['config_json']), json.loads(hf.attrs['runtime_params_json'])
+ saved = {name: hf[name][:] for name in ('ddf', 'temp', 'flag')}
+ row = report['restart'] = dict(status='running', source=str(SOURCE), source_sha256=sha(SOURCE),
+ start=21280, end=21296, a_steps=0, b_steps=0, extrema={})
+ for label in ('a', 'b'):
+ with create(.002) as sim:
+ sim.load_checkpoint(str(SOURCE if label == 'a' else OUT/'restart-21280.h5'))
+ before = state(sim)
+ assert before['config'] == config and before['runtime'] == runtime
+ checks = compare(dict(arrays=saved, step=21280, config=config, runtime=runtime), before)
+ row[label+'_initial_equal'] = checks
+ assert all(checks.values()), checks
+ mass0 = float(observables(populations(sim))[0].sum())
+ check_step(sim, mass0, row['extrema'])
+ if label == 'a':
+ row['checkpoint'] = persist(sim, 'restart-21280.h5')
+ for _ in range(16):
+ sim.run(1)
+ row[label+'_steps'] += 1
+ check_step(sim, mass0, row['extrema'])
+ if label == 'a':
+ expected = state(sim)
+ row['reference_end'] = persist(sim, 'restart-reference-21296.h5')
+ else:
+ row['continued_equal'] = compare(expected, state(sim))
+ row['status'] = 'passed' if all(row['continued_equal'].values()) else 'failed'
+ save()
+ assert row['status'] == 'passed', row['continued_equal']
+ print('RESTART', json.dumps(row), flush=True)
+
+
+def zero(report, save):
+ row = report['zero'] = dict(status='running', steps=0, history=[], extrema={},
+ steady='not_tested_short_case', flux_relative='not_applicable_zero_reference')
+ with create(0.) as sim:
+ sim.initialize()
+ mass0 = float(observables(populations(sim))[0].sum())
+ for step in range(65):
+ if step:
+ sim.run(1)
+ row['steps'] = step
+ f, fields = check_step(sim, mass0, row['extrema'])
+ sample, _ = measure(f, 0., mass0)
+ sample['step'] = step
+ row['history'].append(sample)
+ if sample['max_speed'] > GATES['zero_speed']:
+ raise RuntimeError(f'Zero speed exceeds gate at {step}')
+ if np.ptp([s['mass'] for s in row['history']])/mass0 > GATES['mass_window_span']:
+ raise RuntimeError(f'Zero mass span exceeds gate at {step}')
+ if step and abs(sample['mass']-row['history'][-2]['mass'])/mass0 > GATES['mass_change']:
+ raise RuntimeError(f'Zero mass change exceeds gate at {step}')
+ row['mass_span'] = float(np.ptp([s['mass'] for s in row['history']])/mass0)
+ row['checks'] = dict(zero_speed=row['extrema']['speed'] <= GATES['zero_speed'],
+ mass_offset=row['extrema']['mass_offset'] <= GATES['mass_offset'],
+ mass_span=row['mass_span'] <= GATES['mass_window_span'],
+ mass_change=max(abs(s['mass']-p['mass'])/mass0 for p,s in zip(row['history'],row['history'][1:])) <= GATES['mass_change'],
+ boundary=max(s['boundary_error'] for s in row['history']) <= GATES['boundary_error'],
+ top_density=max(s['top_density_error'] for s in row['history']) <= 5e-7,
+ finite=all(s['finite'] for s in row['history']))
+ row['status'] = 'passed' if all(row['checks'].values()) else 'failed'
+ save()
+ assert row['status'] == 'passed', row['checks']
+ print('ZERO', json.dumps({k:v for k,v in row.items() if k != 'history'}), flush=True)
+
+
+def audit(reference, mass0, report):
+ result = dict(status='running', start=LIMIT-16, end=LIMIT, plain_steps=16, audit_steps=0, steps=[])
+ report['negative']['population_budget'] = result
+ with create(-.002) as sim:
+ sim.load_checkpoint(str(OUT/'negative-budget-20744.h5'))
+ build = compiler.generate_config(sim.lbm_cfg)
+ original = sim.stepper.step_fn
+ try:
+ source = Path(build)/'step/one_step_double.cu'
+ code = source.read_text()
+ call, marker = 'collide_dispatch(f, rho_n, ux, uy);', '__global__ __launch_bounds__(NT, 2)'
+ assert code.count(call) == code.count(marker) == 1
+ source.write_text(code.replace(call, 'j1_collide_audit(f, rho_n, ux, uy);').replace(marker, AUDIT+'\n'+marker))
+ result['audit_source_sha256'] = sha(source)
+ ptx = compiler.compile_kernel(build_dir=build)
+ with sim.ctx.activate():
+ module = compiler.load_module(ptx)
+ ptr, size = module.get_global('d_params')
+ cuda.memcpy_dtod(ptr, sim.field.module.get_global('d_params')[0], size)
+ iptr, _ = module.get_global('j1_incoming')
+ cptr, size = module.get_global('j1_collision')
+ cuda.memset_d8(cptr, 0, size)
+ incoming, collision = np.empty((2,48)), np.empty((35,48))
+ sim.stepper.step_fn = module.get_function('OneStep')
+ slot = targets(-.002)[2]
+ for _ in range(16):
+ before = populations(sim)
+ outgoing = np.stack((before[[4,6,7],1].sum(axis=0), before[[3,5,8],-2].sum(axis=0)))
+ mass = float(before[:,1:-1].sum())
+ sim.run(1)
+ result['audit_steps'] += 1
+ after, _ = check_step(sim, mass0, report['negative']['extrema'])
+ cuda.memcpy_dtoh(incoming, iptr)
+ cuda.memcpy_dtoh(collision, cptr)
+ delta = float(after[:,1:-1].sum()-mass)
+ net = float(incoming.sum()-outgoing.sum())
+ rounding = float(collision.sum())
+ entry = dict(step=sim.stepper.step_count, mass=mass, delta_mass=delta,
+ net_boundary=net, collision_roundoff=rounding,
+ physical_residual=delta-net, budget_residual=delta-net-rounding,
+ exchange={name:dict(incoming=float(i.sum()), outgoing=float(o.sum()))
+ for name,i,o in [('slot',incoming[0,slot],outgoing[0,slot]),
+ ('flanks',incoming[0,~slot],outgoing[0,~slot]),
+ ('top',incoming[1],outgoing[1])]})
+ result['steps'].append(entry)
+ if abs(entry['budget_residual'])/mass > GATES['budget_residual']:
+ raise RuntimeError('Population budget gate exceeded')
+ result['continued_equal'] = compare(reference, state(sim))
+ result['max_relative_residual'] = max(abs(s['budget_residual'])/s['mass'] for s in result['steps'])
+ result['max_physical_relative_residual'] = max(abs(s['physical_residual'])/s['mass'] for s in result['steps'])
+ result['status'] = 'passed' if all(result['continued_equal'].values()) else 'failed'
+ finally:
+ sim.stepper.step_fn = original
+ compiler.cleanup_build_dir(build)
+ return result
+
+
+def negative(report, save):
+ row = report['negative'] = dict(status='running', amplitude=-.002, steps=0, main_steps=0,
+ history=[], extrema={}, population_budget=dict(status='not_tested'))
+ with create(-.002) as sim:
+ sim.initialize()
+ initial = populations(sim)
+ mass0 = float(observables(initial)[0].sum())
+ first, fields = measure(initial, -.002, mass0)
+ first.update(step=0)
+ row['history'].append(first)
+ bottom, top, _ = targets(-.002)
+ row['initial_error'] = float(max(np.abs(fields[2][0]-bottom).max(), np.abs(fields[2][-1]-top).max(), np.abs(fields[1]).max()))
+ previous, mass_previous = fields[1:], mass0
+ check_step(sim, mass0, row['extrema'])
+ try:
+ for interval in range(1,41):
+ mean = np.zeros((2,33,48)); m2 = np.zeros_like(mean)
+ low, high = np.full_like(mean, np.inf), np.full_like(mean, -np.inf)
+ for n in range(1,CHUNK+1):
+ if sim.stepper.step_count == LIMIT-16:
+ row['budget_start'] = persist(sim, 'negative-budget-20744.h5')
+ sim.run(1)
+ row['steps'] = row['main_steps'] = sim.stepper.step_count
+ f, fields = check_step(sim, mass0, row['extrema'])
+ uv = np.stack(fields[1:])
+ delta = uv-mean
+ mean += delta/n
+ m2 += delta*(uv-mean)
+ low, high = np.minimum(low,uv), np.maximum(high,uv)
+ sample, fields = measure(f, -.002, mass0, previous)
+ sample.update(step=sim.stepper.step_count, mass_change=abs(sample['mass']-mass_previous)/mass0,
+ fluctuation=dict(samples=CHUNK, first_step=sim.stepper.step_count-CHUNK+1,
+ rms=np.sqrt(np.mean(m2/CHUNK,axis=(1,2))).tolist(),
+ max_node_peak_to_peak=np.max(high-low,axis=(1,2)).tolist()))
+ row['history'].append(sample)
+ sample['mass_window_span'] = float(np.ptp([s['mass'] for s in row['history'][-5:]])/mass0)
+ previous, mass_previous = fields[1:], sample['mass']
+ save()
+ print('NEGATIVE', json.dumps({k:sample[k] for k in ('step','mass_offset','mass_change','mass_window_span','u_change','v_change','flux_error','boundary_error')}), flush=True)
+ if sample['mass_change'] > GATES['mass_change'] or sample['mass_window_span'] > GATES['mass_window_span']:
+ raise RuntimeError('Negative sampled mass hard gate exceeded')
+ assert resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024 < 512
+ reference = state(sim)
+ row['end_checkpoint'] = persist(sim, 'negative-end-20760.h5')
+ row['final_boundary'] = dict(bottom_rho=fields[0][0].tolist(), bottom_u=fields[1][0].tolist(),
+ bottom_v=fields[2][0].tolist(), top_rho=fields[0][-1].tolist(),
+ top_u=fields[1][-1].tolist(), top_v=fields[2][-1].tolist())
+ except Exception:
+ row['failure_checkpoint'] = persist(sim, 'negative-failure.h5')
+ raise
+ budget = audit(reference, mass0, report)
+ last, tail = row['history'][-1], row['history'][-4:]
+ checks = dict(steady=len(row['history']) >= 9 and all(s['u_change'] <= GATES['velocity_change'] and s['v_change'] <= GATES['velocity_change'] and s['mass_change'] <= GATES['mass_change'] for s in tail) and last['mass_window_span'] <= GATES['mass_window_span'],
+ initialization=row['initial_error'] <= GATES['boundary_error'],
+ boundary=last['boundary_error'] <= GATES['boundary_error'],
+ top_density=last['top_density_error'] <= 5e-7,
+ mass=last['mass_offset'] <= GATES['mass_offset'] and last['mass_window_span'] <= GATES['mass_window_span'],
+ bounded=last['rho_error'] <= GATES['rho_error'] and last['max_speed'] <= GATES['speed'],
+ flux=last['flux_error'] <= GATES['flux_error'] and last['flux_span'] <= GATES['flux_span'],
+ symmetry=last['symmetry']['rho'] <= GATES['rho_symmetry'] and max(last['symmetry']['u'],last['symmetry']['v']) <= GATES['velocity_symmetry'],
+ nonuniform=last['nonuniform'], audit=budget['status'] == 'passed' and budget['max_relative_residual'] <= GATES['budget_residual'])
+ row['checks'] = {k:bool(v) for k,v in checks.items()}
+ row['status'] = 'passed' if all(checks.values()) else 'failed'
+ save()
+ print('NEGATIVE RESULT',json.dumps(row['checks']),flush=True)
+
+
+def main():
+ assert Path.cwd() == ROOT == Path('/home/frank14f/CelerisLab')
+ assert sys.executable == '/home/frank14f/anaconda3/envs/pycuda_3_10/bin/python'
+ assert Path(CelerisLab.__file__).resolve() == ROOT/'src/CelerisLab/__init__.py'
+ assert Path(compiler.kernel_path('kernel_v2.cu')).resolve() == ROOT/'src/CelerisLab/lbm/kernels/kernel_v2.cu'
+ assert os.environ.get('CUDA_VISIBLE_DEVICES') == '0'
+ assert not (OUT/'results.json').exists(), 'Do not repeat this run'
+ baseline = json.loads((OUT/'baseline.json').read_text())
+ assert all(sha(ROOT/name) == digest for name,digest in baseline['hashes'].items())
+ assert sha(SOURCE) == SOURCE_SHA
+ gpu = subprocess.check_output(['nvidia-smi','-i','0','--query-gpu=memory.used,utilization.gpu','--format=csv,noheader,nounits'],text=True)
+ used, utilization = map(int,gpu.strip().split(','))
+ apps = subprocess.check_output(['nvidia-smi','-i','0','--query-compute-apps=pid','--format=csv,noheader'],text=True)
+ assert not apps.strip() and used < 100 and utilization == 0, (gpu,apps)
+ report = dict(python=sys.executable, package=CelerisLab.__file__, cuda_source=compiler.kernel_path('kernel_v2.cu'),
+ script_sha256=sha(__file__), gpu='0', gpu_before=gpu, gates=dict(GATES,top_density_error=5e-7),
+ restart=dict(status='not_tested'),zero=dict(status='not_tested'),negative=dict(status='not_tested'))
+
+ def save():
+ report['peak_rss_mib'] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024
+ (OUT/'results.json').write_text(json.dumps(report,indent=2)+'\n')
+
+ print('SOURCES',report['python'],report['package'],report['cuda_source'],flush=True)
+ save()
+ try:
+ restart(report,save)
+ zero(report,save)
+ negative(report,save)
+ except Exception as error:
+ report['error'] = repr(error)
+ for name in ('restart','zero','negative'):
+ if report[name]['status'] == 'running': report[name]['status'] = 'failed'
+ budget = report['negative'].get('population_budget', {})
+ if budget.get('status') == 'running': budget['status'] = 'failed'
+ traceback.print_exc()
+ finally:
+ report['old_files_unchanged'] = all(sha(ROOT/name) == digest for name,digest in baseline['hashes'].items())
+ save()
+ print('FINAL',json.dumps({name:report[name]['status'] for name in ('restart','zero','negative')}),flush=True)
+ return 0 if report['old_files_unchanged'] and all(report[n]['status']=='passed' for n in ('restart','zero','negative')) else 1
+
+
+if __name__ == '__main__':
+ raise SystemExit(main())
Binary file not shown.
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,31 @@
{
"old_files_verified": 257,
"changed_old_files": [],
"new_code_files": [
"tests/validation/run_j3_coverage.py"
],
"production_changes": 0,
"script_sha256": "329869519b7078e854d96241a7aad8ef93f35ac9be83f0be502c3a93523c3b13",
"checkpoint_hashes_verified": 4,
"solver_advances": {
"restart_a": 16,
"restart_b": 16,
"zero": 64,
"negative_plain": 20760,
"negative_overlapping_audit": 16
},
"gpu_after": "GPU0: 5 MiB, 0%, no compute process",
"git_diff_check": "passed",
"artifacts": {
"REVIEW.md": "7293f3f3442855c8521698605aab504e026915a7bf1e77f5a24710d89a812443",
"baseline-status.txt": "31c949b11b20d7cd4202dba16882b5712aa1653da0cb2da2f0ebd69bf488040e",
"baseline.json": "d8844104f2665a25bfc417ee29becf89ab3955fac9105b5ddb12cfb1fe2a55b0",
"gpu-validation.log": "505cd5a5db46d7984aefb2a614151c25c4ace0e7d2a52e02c3e4f9792fd8eb95",
"incremental.diff": "98aa7855d5d6b91b4509a924c8a5aabab4339ba29c7e7dc2d91262c48e3848ca",
"negative-budget-20744.h5": "c09d75fc4a2cff68039a0956bd9d32b79b9cd3a6b386c72b4db54c214b110cd8",
"negative-end-20760.h5": "bd0bd063579d625e358762b1fdde5ac11bfcf739646a847fb77a4a2031011b9b",
"restart-21280.h5": "3e89c12c16f91f76ca9acd909e0fa7d42df6fbb5e870b299aa08ca42bc3e3dc9",
"restart-reference-21296.h5": "7192f510dd7820675aa1de130f55514136fba782cf77f92545189918a7e0c328",
"results.json": "02460981ad49c9cc13b4246abad1d8afd2599c61bfb545a6e32da9bbcd5c0db1"
}
}