Seal Phase 4AG author-APL audit and fixed CAL failure
This commit is contained in:
+12
-17
@@ -1,30 +1,25 @@
|
|||||||
# Digital Drosophila — 当前状态
|
# Digital Drosophila — 当前状态
|
||||||
|
|
||||||
更新:2026-09-30。分支:`codex/lif-author-semantics-lab`。
|
更新:2026-09-30。独立分支:`codex/lif-author-semantics-lab`。
|
||||||
|
|
||||||
## 最新结果
|
## 最新结果
|
||||||
|
|
||||||
Phase4AF:**PASS-SHORT-FULLGRAPH-NUMERICAL-GATE**,已独立封存。
|
Phase 4AG-r2:**FAIL-FIXED-CAL-REPRESENTATION**,已封存。
|
||||||
完整166,700神经元/25,582,938边/124,177,617contacts,保留217isolates和101self-loops。
|
|
||||||
无输入10ms、单seed50ms、固定五seed50ms三条轨迹,Brian作者float64与GPU每tick状态逐bit一致,放电/请求/队列顺序一致。
|
|
||||||
三个trial事件数0/24,398/24,983;没有NaN/Inf或数值分歧。
|
|
||||||
旧五组deterministic-v2 frozen reference再次精确PASS;原230,239项及4AA–4AE封存前后checksum全部PASS。
|
|
||||||
|
|
||||||
前序4AD作者oracle已验证,4AE固定小图数值压力集72/72GPU测试通过。旧phase结论和失败记录保留不改。
|
作者 float64 LIF + 原 float32 graded APL 的数值门槛通过;8 个小型场景和两个完整全图 100 ms probe 与共享 APL 组件的 Brian 闭环对照精确一致。全图仍为 166,700 神经元、25,582,938 边,原始 contact sum 124,177,617。
|
||||||
|
|
||||||
## 仍未证明
|
固定 6 气味 × 5 seed × 2 模式的 60 次 CAL 均完整且有限,12 次重复精确通过。但 KC 平均活跃比例为 **1.2713% / 1.2336%**,低于原固定 3%–9% 门槛。其余原 CAL 条件通过,成对距离判据通过数为 **12/15、13/15**;这不是学习成功率或 held-out 泛化证明。
|
||||||
|
|
||||||
尚无learning candidate;没有证明长期全脑等价、生理正确、heldout odor separation或条件反射记忆。
|
旧五组 deterministic-v2 参考精确通过;原 230,239 项及后续封存目录 checksum 全部通过。v1 的执行入口失败及 r2 修复记录均保留。原 raw/CSR/reference/runtime/APL 参数/eligibility-v2/14,232-edge mask 不改。
|
||||||
4AF明确无APL overlay、无训练、无heldout;短轨迹PASS不能替代嗅觉CAL。
|
|
||||||
GPU诊断含CPU逐步同步/校验,不是实时性能候选。
|
前序 Phase 4AF 的短时全图数值 PASS 保留。没有学习候选,没有训练,不进入游戏/RL/decoder/Web。
|
||||||
|
|
||||||
## 下一步
|
## 下一步
|
||||||
|
|
||||||
1. 先进行author LIF + frozen legacy graded APL显式语义兼容gate,保留原参数/mask;重点验证reset/refractory无条件写入、float32及mV→SI转换。
|
先只读分析已有 CAL 记录:输入实际接受 → PN→KC 真实延迟投递 → 不应期/reset → APL 写入,解释低 KC 覆盖率。APL 是否为原因尚未证明;不调参、改门槛或增加刺激来追求通过。
|
||||||
2. 通过后再跑固定DoOR CAL,不学习、不用heldout调参。
|
|
||||||
3. 信息保持→独立seed/新odor→credit→isolated/wholebrain functional gate均通过后,才开始真正learning验证。
|
|
||||||
|
|
||||||
不进入游戏、RL、decoder或Web。旧base CSR/W_syn/sign/APL calibration/eligibility-v2/14,232-edge plastic mask及封存文件只读。
|
后续仍需独立 seed/新气味表征、信用分配、隔离功能及全脑功能检查,不能由数值一致性推导学习可用。
|
||||||
服务器上保留完整新状态约5.11GB;Git仅同步代码、小报告、provenance和checksum,不等于全量异机备份。
|
|
||||||
|
|
||||||
[最新解释](docs/progress/phase4af-interpretation.md) · [实验报告](docs/progress/phase4af-author-fullgraph.md) · [APL兼容审计准备](docs/progress/phase4af-apl-next-gate.md) · [封存校验](registry/phase4af-author-fullgraph/seal-verification.json)
|
完整新实验数组保存在服务器;Git 只同步代码、小型报告及校验记录,不是全量异机备份。诊断耗时包含逐步校验,不是实时性能基准。
|
||||||
|
|
||||||
|
[最终解释](docs/progress/phase4ag-interpretation.md) · [正式实验报告](docs/progress/phase4ag-author-apl-r2.md) · [封存校验](registry/phase4ag-author-apl-r2/seal-verification.json)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Phase 4AG: author LIF + unchanged legacy graded APL
|
||||||
|
|
||||||
|
Status: `FAIL-FIXED-CAL-REPRESENTATION`.
|
||||||
|
|
||||||
|
Numerical closed-loop gate: True; original complete fixed six-CAL gate: False.
|
||||||
|
The independent Brian LIF and candidate use independent state but share the APL arithmetic component. Original frozen APL AST replay and a float64 error audit are separately recorded.
|
||||||
|
Author LIF uses float64; APL retains float32, tau20ms/gain0.01/normalization1, full original matrices and order. No learning/parameter search.
|
||||||
|
The explicitly hypothesized unconditional end-APL write includes refractory KC. Original fast APL mask leaves1,212 non-KC edges unreplaced; this scope limitation was not silently fixed.
|
||||||
|
Old checksums and five frozen reference trials: True.
|
||||||
|
Successfully compared cases: [{'case': 'apl_only', 'pass_all': True}, {'case': 'arrival_collision', 'pass_all': True}, {'case': 'cal-matched_energy-00-s51101', 'pass_all': True}, {'case': 'cal-physiological-00-s51101', 'pass_all': True}, {'case': 'high_fanin', 'pass_all': True}, {'case': 'kc_ref_boundary', 'pass_all': True}, {'case': 'natural_request', 'pass_all': True}, {'case': 'pn_pulse', 'pass_all': True}, {'case': 'two_sources', 'pass_all': True}, {'case': 'zero', 'pass_all': True}].
|
||||||
|
Detailed CAL, exact comparisons, component errors, event/request traces and execution exceptions are linked from audit/final-status.json.
|
||||||
|
Wall/VRAM here include per-tick CPU synchronization, IPC and hashes. They are diagnostic costs, not runtime-performance benchmarks.
|
||||||
|
No heldout dynamic outputs, formal A/B, learning, game, reward, decoder or new candidate.
|
||||||
|
Next gate: Audit first failure in this explicitly declared hypothesis; no gain search, no heldout tuning, no conditioning
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Phase 4AG: author LIF + unchanged legacy graded APL
|
||||||
|
|
||||||
|
Status: `INCOMPLETE-NUMERICAL-EXECUTION`.
|
||||||
|
|
||||||
|
Numerical closed-loop gate: False; original complete fixed six-CAL gate: False.
|
||||||
|
The independent Brian LIF and candidate use independent state but share the APL arithmetic component. Original frozen APL AST replay and a float64 error audit are separately recorded.
|
||||||
|
Author LIF uses float64; APL retains float32, tau20ms/gain0.01/normalization1, full original matrices and order. No learning/parameter search.
|
||||||
|
The explicitly hypothesized unconditional end-APL write includes refractory KC. Original fast APL mask leaves1,212 non-KC edges unreplaced; this scope limitation was not silently fixed.
|
||||||
|
Old checksums and five frozen reference trials: True.
|
||||||
|
Successfully compared cases: [].
|
||||||
|
Detailed CAL, exact comparisons, component errors, event/request traces and execution exceptions are linked from audit/final-status.json.
|
||||||
|
Wall/VRAM here include per-tick CPU synchronization, IPC and hashes. They are diagnostic costs, not runtime-performance benchmarks.
|
||||||
|
No heldout dynamic outputs, formal A/B, learning, game, reward, decoder or new candidate.
|
||||||
|
Next gate: Audit first failure in this explicitly declared hypothesis; no gain search, no heldout tuning, no conditioning
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Phase 4AG:设计、证据范围与限制
|
||||||
|
|
||||||
|
本文是独立于已登记模型和实验文件的解释性文档,不是预注册协议的修订,也不是最终实验报告。状态快照日期:2026-09-30。
|
||||||
|
|
||||||
|
在本说明对应的检查节点,r2 的 8 个固定小型测试场景已完成每场景 3 次 GPU 运行及 1 次 Brian 对照,数值门禁通过;两个预先指定的全图 100 ms Brian 对照也已通过。后续 60 次 CAL 基础运行和 12 次重复检查仍在进行中。本文不宣布 CAL 通过或失败,更不宣布学习成功。正式状态应以各阶段原始审计记录及最终封存报告为准。
|
||||||
|
|
||||||
|
## 本阶段到底测试什么
|
||||||
|
|
||||||
|
Phase 4AG 测试一个明确的新组合:在 MaleCNS 原有全图上,将已经核对过作者语义的 float64 LIF 动力学,与项目旧版 float32 graded APL 模块连接起来,先检查实现是否符合声明,再检查固定旧 CAL 输入下的嗅觉表征是否满足完整原门槛。
|
||||||
|
|
||||||
|
全图仍为 166,700 个神经元、25,582,938 条规范化有向边。原始连接计数、递质符号、W_syn、旧 APL 参数以及 eligibility-v2 的 14,232 边掩码不修改。本阶段不训练,不搜索增益、阈值、刺激强度或时间窗,不新增连接,不做行为、奖励或游戏演示。
|
||||||
|
|
||||||
|
作者语义来源是已归档的 Shiu 等人代码,而不是重新选取的最新版本:GitHub commit `91bdd1e7dcf193f3e7ca5a8933497fcef63b7960`,归档 `model.py` 的 SHA-256 为 `fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e`。[固定提交的作者代码](https://github.com/philshiu/Drosophila_brain_model/blob/91bdd1e7dcf193f3e7ca5a8933497fcef63b7960/model.py) 对应 Shiu 等人的论文 [A Drosophila computational brain model reveals sensorimotor processing](https://www.nature.com/articles/s41586-024-07763-9)(Nature,2024)。本项目使用不同的连接组及额外的旧 APL 工程模块,因此不能称为该论文或作者完整模型的严格复现。
|
||||||
|
|
||||||
|
## 混合精度与每一步的明确顺序
|
||||||
|
|
||||||
|
LIF 的 `v`、`g` 和解剖边权使用 float64、SI 伏特;这里的 `g` 是作者方程中以伏特表示的状态量,不应仅凭变量名解释成电导。LIF 核心复用已封存的 CUDA 运算,不修改数学语义。固定步长为 0.1 ms,解剖传递延迟为 18 步,不应期为 22 步。
|
||||||
|
|
||||||
|
APL 则保留旧环境中的 float32 矩阵、状态和运算序列。输入矩阵始终是 `2 × 166700`,输出矩阵始终是 `2 × 4064`;即使测试小型诱导子图,也不裁剪矩阵或重算归一化。每次独立运行从零 APL 状态开始。APL 输入是本步实际产生的二值放电,而不是外部请求:被不应期拒绝的请求不能被当作放电反馈。
|
||||||
|
|
||||||
|
每步先完成 LIF 核心、请求处理、真实延迟到达和复位的声明调度,再在 `end` 执行旧 APL。APL 衰减与增加保持分开的 eager 操作:
|
||||||
|
|
||||||
|
```text
|
||||||
|
s32.mul_(float(float32(exp(-0.1 / 20.0))))
|
||||||
|
drive32 = torch.mv(I32, actual_spikes32)
|
||||||
|
s32.add_(drive32)
|
||||||
|
h32 = torch.matmul(s32, O32) * float32(0.01)
|
||||||
|
|
||||||
|
delta64 = h32.to(float64) * float64(0.001)
|
||||||
|
g64[KC] = g64[KC] - delta64
|
||||||
|
```
|
||||||
|
|
||||||
|
其中 `h32` 沿用旧模块的 mV 语义。必须先拓宽为 float64,再乘 0.001 转成伏特,最后单独减去;不能先在 float32 中乘 0.001,也不能将 `mul_`、`add_` 或最后的转换与减法融合成另一条运算路径。tau=20 ms、gain=0.01、normalization=1 均不调整,也不额外加入 APL 延迟、裁剪或 `dt/tau` 缩放。
|
||||||
|
|
||||||
|
APL 不改变原环境的默认 TF32/矩阵乘精度/CuBLAS 设置,而是记录实际设置、版本和设备,并核对组件输出。保留“数学上等价”的表达式并不足以保证逐位相同;PyTorch 官方说明明确指出,浮点运算顺序、后端和版本都可能影响结果。[PyTorch 数值精度说明](https://docs.pytorch.org/docs/2.14/notes/numerical_accuracy.html)、[可复现性说明](https://docs.pytorch.org/docs/2.14/notes/randomness.html) 在此用于解释工程风险,不作为改变冻结环境的理由;文档不能替代实验记录中的实际安装版本和设备信息。
|
||||||
|
|
||||||
|
## 不应期中的 APL 写入是被检验的假设
|
||||||
|
|
||||||
|
本组合在复位后的 `end` 阶段,无条件向所有对应 KC 的 `g` 写入 APL 抑制,包括刚放电或仍处于不应期的 KC。这里没有补加 `ref == 0` 条件。
|
||||||
|
|
||||||
|
这必须与作者核心的普通解剖输入区分:作者方程中带有 `unless refractory` 的状态在不应期冻结,普通突触更新受相应保护;本分支的 APL 是显式的末尾直接状态写入,不是把它伪装成普通受保护突触。[Brian 2.5.1 不应期文档](https://brian2.readthedocs.io/en/2.5.1/user/refractoriness.html) 解释了不应期和状态冻结的区别;具体执行依据仍是已归档作者代码及本项目保存的实际生成代码。
|
||||||
|
|
||||||
|
由这套代码顺序可以推得:APL 写入的负 `g` 可能在不应期内继续累积,而该期间作者核心不会按通常的 `g` 方程衰减它。这个组合效应是此次被检验的显式工程假设,不是已确认的生理机制,也不是作者原模型的主张。若改成不应期屏蔽、写入后再次清零或更换写入阶段,就已经是另一项假设,不能作为此次结果不好时的即时“修复”。
|
||||||
|
|
||||||
|
## 5,845 条 fast APL 掩码及 1,212 条未替换边
|
||||||
|
|
||||||
|
旧 APL 模块的兼容规则是:将全部 5,845 条原始 APL fast 出边的有效权重置零,然后仅向 KC 提供 graded 替代。置零只发生在新运行时的内存副本中;磁盘上的原始图、计数、符号和基础权重不改写,边身份也不删除。
|
||||||
|
|
||||||
|
其中 1,212 条出边的目标不是 KC,因此其 fast 作用被关闭后,没有获得本模块的 graded 替代。这是已知且保留的覆盖缺口。不能把该组合描述成“所有 APL 输出均被等价替换”,也不能为了得到更好的结果悄悄恢复这些边或新增非 KC 的 graded 通路。这两个数字描述的是本项目图中的有向边计数,不是新增的生物学结论。
|
||||||
|
|
||||||
|
## 三类数值证据分别能说明什么
|
||||||
|
|
||||||
|
| 检查 | 能支持的结论 | 不能支持的结论 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Brian 闭环对照 | Brian 自己推进 LIF、产生实际放电,独立进程中的 APL 状态据此更新;与 GPU 比较逐步状态、事件、请求、队列顺序与接受掩码、APL drive/state/h | APL 算法本身完全独立实现,或所有输入下的普遍等价 |
|
||||||
|
| 原代码 AST 影子重放 | 从冻结旧初始化代码重建矩阵,并提取旧更新语句;用已记录的真实放电重放,检查组件字节是否保持一致 | 新的独立全脑闭环证明,或摆脱共同 Torch/CUDA 底层原语的验证 |
|
||||||
|
| float64 算术测量与误差界 | 在明确的非负矩阵、正常有限运算等前提下,量化 float32 组件相对独立 float64 测量的偏差,检查预先定义的误差界 | 用 float64 替换 APL、事后放宽容差,或用误差界替代逐位旧组件一致性 |
|
||||||
|
|
||||||
|
Brian 的 APL worker 不接收候选 GPU 的抑制轨迹,而只接收 Brian 自己产生的实际放电;它有独立的零初始状态,并通过握手核对矩阵哈希与运行环境。但候选与 worker 共享 APL 组件实现,所以准确名称是“共享 APL 组件的闭环 Brian 对照”,不能写成“全部组件独立的 CPU oracle”。
|
||||||
|
|
||||||
|
AST 影子又提供一层不同的代码来源检查,但仍使用相同的 Torch/CUDA 原语。float64 测量不反馈到任一脑模型,其误差界不根据观测误差拟合。各证据应并列阅读,不能互相替代。
|
||||||
|
|
||||||
|
8 个固定小型场景检验零输入、真实 PN/KC 输入、不应期边界、自然放电与请求重合、延迟到达、APL mask 和高 fan-in 等情形;每场景 3 次 GPU 运行检查精确重复。两个全图 probe 是预先指定的第一个旧 CAL 气味、首个原始 seed、两种编码模式,各 100 ms。通过这些检查只说明已测试场景符合本组合的声明,不证明所有气味、时间尺度或后续学习任务都有效。同步、IPC、逐步哈希和诊断保存的耗时也不是性能基准。
|
||||||
|
|
||||||
|
## CAL 必须通过完整原 4L 门槛
|
||||||
|
|
||||||
|
CAL 设计固定为原 6 个校准气味 × 5 个原始 seed(51101–51105)× 2 种模式(`physiological`、`matched_energy`),共 60 次基础运行,每次 100 ms;每个气味/模式的首个 seed 再运行一次,共 12 次重复。它们不是额外的训练 seed。
|
||||||
|
|
||||||
|
输入在任何轨迹运行前保存,保留旧 PN 编码、目标/随机数列顺序。matched-energy 的参考值仍取原冻结 12 气味 panel 的中位数,不能换成 6 CAL 的中位数,也不能换成后续其他 panel。读取这份静态参考数据不等于读取 heldout 动态结果。
|
||||||
|
|
||||||
|
每种模式都必须同时满足以下原始条件,两种模式都通过才满足表征门槛:
|
||||||
|
|
||||||
|
- KC 活跃比例的平均值在闭区间 3%–9%。
|
||||||
|
- 单次运行的最小活跃比例严格大于 0,最大值严格小于 50%。
|
||||||
|
- 同气味跨 seed 的平均活跃集 Jaccard,严格大于不同气味同 seed 的平均 Jaccard。
|
||||||
|
- 不同气味同 seed 的平均欧氏距离,严格大于同气味跨 seed 的平均欧氏距离。
|
||||||
|
- 至少 3 对气味通过成对分离检查:该对气味在相同 seed 下的 5 个距离均值,严格大于这两个气味各自全部 10 个跨 seed 距离合并后的 20 项均值。
|
||||||
|
|
||||||
|
距离来自原始 KC spike-count 向量,欧氏距离先转 float64,不另做向量归一化;Jaccard 使用是否放电的布尔活跃集。6 CAL 每种模式有 15 对气味、60 项 within 距离和 75 项 between 距离。成对比较的基线不是全部气味混在一起的平均 within 距离;只检查平均稀疏率与“至少 3 对”的旧简化 `r4` 不能代替完整原 4L 门槛。
|
||||||
|
|
||||||
|
本阶段另加输出完整性、有限值和 12 次精确重复要求;缺失文件、失败运行、NaN 或全静默都不能当成通过。原 4L 虽记录 finite,但没有将它写进原最终 gate,因此这里应明确称为新增的完整性前置检查,而非改写历史。
|
||||||
|
|
||||||
|
即使最终 CAL 通过,含义也仅限于这组固定校准输入下的表征检查。它不等于 heldout 泛化、刺激特异性信用分配、记忆、条件化或可用学习;本阶段没有训练或生成新的候选模型结论。后续学习验证仍需在授权范围内另行登记并通过专门门槛,不能由本阶段的数值一致性推导出来。
|
||||||
|
|
||||||
|
## 为什么保留 v1,并单独运行 r2
|
||||||
|
|
||||||
|
第一次登记的 v1 在启动 APL worker 时,对科学虚拟环境的 Python 路径调用了 `resolve()`,跟随符号链接到了系统解释器,丢失预期包环境。异常发生在首个 Brian tick 之前,错误记录的 `last_complete_tick` 为 -1;v1 已保留源代码、部分输出和故障记录,并以 `INCOMPLETE-NUMERICAL-EXECUTION` 封存。
|
||||||
|
|
||||||
|
这不是已观测到的动力学或科学假设失败,也不能反过来称作数值通过。r2 使用新模型目录 `author-apl-lab-v2` 和新实验目录 `phase4ag-author-apl-r2`,保留虚拟环境的调用入口路径,只修执行入口及相应记录/检查,不更改方程、运算精度、掩码、刺激、门槛、参数或测试选择。全部声明流程从新状态重跑,不覆盖或挑选性省略 v1 的记录。
|
||||||
|
|
||||||
|
本文所述已通过的 r2 数值门禁与仍在进行的 CAL 是两件事。是否完成、是否通过,以及允许得出的结论,最终都必须回到对应原始证据和封存状态,而不是依据本解释文档升级。
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
# Phase 4AG:独立动力学分支的正式结果
|
||||||
|
|
||||||
|
更新:2026-09-30。实验:`phase4ag-author-apl-r2`;模型:`author-apl-lab-v2`;Git 分支:`codex/lif-author-semantics-lab`。
|
||||||
|
|
||||||
|
## 结论
|
||||||
|
|
||||||
|
正式状态:**FAIL-FIXED-CAL-REPRESENTATION**。
|
||||||
|
|
||||||
|
本轮完成作者 float64 LIF 与冻结旧 float32 graded APL 的显式组合测试。数值一致性、数据完整性和精确重复检查通过;固定 CAL 的完整原门槛未通过。没有训练,没有新学习候选,不升级原 reference/runtime,也不修改旧模型。
|
||||||
|
|
||||||
|
两种输入模式唯一未达标条件都是 KC 平均活跃比例低于预先固定的 3%–9%。这不证明约 1.2% 的活跃比例在生物学上错误,也不能据此认定 APL 是原因。
|
||||||
|
|
||||||
|
## 固定 CAL:60 次基础运行及 12 次重复
|
||||||
|
|
||||||
|
使用原 6 个 CAL 气味、原 5 个 seed、两种输入模式,每次 100 ms;每个气味/模式首个 seed 再运行一次。未读取 held-out 动态结果,未做正式 A/B conditioning。
|
||||||
|
|
||||||
|
| 指标 | physiological | matched_energy |
|
||||||
|
| --- | ---: | ---: |
|
||||||
|
| KC 平均活跃比例 | 1.271325% | 1.233596% |
|
||||||
|
| 单次最少/最多活跃 KC(共 4,064) | 38 / 79 | 36 / 72 |
|
||||||
|
| 同气味跨 seed 平均 Jaccard | 0.509072 | 0.516431 |
|
||||||
|
| 不同气味同 seed 平均 Jaccard | 0.460955 | 0.481702 |
|
||||||
|
| 同气味平均欧氏距离 | 5.811443 | 5.671828 |
|
||||||
|
| 不同气味平均欧氏距离 | 6.205091 | 5.932021 |
|
||||||
|
| 成对距离判据通过数 | 12 / 15 | 13 / 15 |
|
||||||
|
| 完整原 CAL 门槛 | FAIL | FAIL |
|
||||||
|
|
||||||
|
其余原条件全部通过:单次最小活跃比例大于零、最大值小于 50%、同气味 Jaccard 大于不同气味、不同气味欧氏距离大于同气味、至少 3 对气味满足原成对距离判据。该判据使用每对气味自己的 20 项 within 距离与 5 项 same-seed between 距离,不是全气味混合基线。
|
||||||
|
|
||||||
|
60/60 基础运行完整、有限;12/12 重复的事件、状态、逐 tick 哈希、APL 轨迹、请求及队列均精确一致。未见 NaN/Inf。12/15 和 13/15 不是学习成功率、统计显著性或 held-out 泛化结论。
|
||||||
|
|
||||||
|
matched-energy 保持原冻结 12 气味静态 panel 中位数及原随机输入算法;它匹配期望输入量,不保证每次随机运行实际接受事件相等。其期望事件数 CV 约 6.48e-8,实际接受事件 CV 为 0.134355;不得称作实际输入事件数严格匹配实验。
|
||||||
|
|
||||||
|
## 数值证据与完整性
|
||||||
|
|
||||||
|
- 8 个固定真实诱导子图场景,各 3 次 GPU 和 1 次 Brian 闭环对照;16 个 GPU 重复比较通过。
|
||||||
|
- 两个预指定完整全图 100 ms probe,逐 tick 的 v/g/ref、放电事件、请求、延迟队列及 APL drive/state/h 精确一致。
|
||||||
|
- 10 组原 APL AST 组件重放/误差审计通过。两个 Python 环境分别通过 29 项协议/汇总/解释器入口单元测试。
|
||||||
|
- 全图保留 166,700 神经元、25,582,938 条边,原始 contact weight sum 为 124,177,617;原始磁盘 CSR 不改。
|
||||||
|
- 原 230,239 项冻结清单及后续已封存目录全部校验通过;旧五组 deterministic-v2 参考的事件、计数、最终 v/g 再次精确通过。
|
||||||
|
- 新 r2 模型 17 项、新实验 1,718 项已封存并再次验证。实验封存前 payload 为 2,956,599,228 字节(约 2.75 GiB)。
|
||||||
|
|
||||||
|
Brian 独立推进 LIF,但 APL worker 与候选共享 APL 算术组件;AST 重放也使用相同底层 Torch/CUDA 原语。因此是“共享 APL 组件的闭环对照”,不是全部组件独立的 CPU oracle,也不是任意输入/长期全脑普遍等价证明。float64 误差测量不反馈到模型。
|
||||||
|
|
||||||
|
诊断包含逐步 CPU 同步、哈希、IPC 和保存,耗时不代表正式 runtime 性能;没有由本轮产生新的实时运行候选。
|
||||||
|
|
||||||
|
## 已声明的假设与保留的问题
|
||||||
|
|
||||||
|
APL 保留旧 float32 矩阵、tau=20 ms、gain=0.01、normalization=1;LIF 为作者 float64 语义。APL 在 reset 后的 end 阶段无条件写入 KC g,包括不应期,先拓宽 float64 再由 mV 转 SI。作者核心在不应期冻结 g,与末尾 APL 写入结合可能产生累积,但本轮尚未定位低 KC 覆盖率的原因。
|
||||||
|
|
||||||
|
旧 APL 规则在独立运行的内存权重副本中关闭 5,845 条 fast APL 出边,只向 KC 提供 graded 替代。其中 1,212 条非 KC 边(13,712 contacts)未获替代。该覆盖缺口原样披露,不静默恢复边或修改归一化。新分支不是作者原始完整模型的严格复现。
|
||||||
|
|
||||||
|
首次 v1 因虚拟环境 Python 符号链接被错误解析到系统解释器而在首个 Brian tick 前中止,正式保存为 `INCOMPLETE-NUMERICAL-EXECUTION`。r2 只修执行入口及检查,另建目录从头运行;全部 68 组输入请求与 v1 一致。失败代码、日志和结果保留,没有覆盖或删除。
|
||||||
|
|
||||||
|
## 下一步:先解释失败,不追逐通过率
|
||||||
|
|
||||||
|
只用现有 60 次 CAL 的记录,先登记一份只读影子记账诊断:
|
||||||
|
|
||||||
|
1. 分解请求数、实际接受量和 PN 实际放电。
|
||||||
|
2. 按真实边及 18-step delay 重建 PN→KC 兴奋性投递、拒绝、不应期和 reset。
|
||||||
|
3. 区分活跃/静默 KC,审计 APL 写入时相、累积量与 g 的关系。
|
||||||
|
4. 先验证重建与已保存事件/最终状态一致,再讨论机制;不足以重建的证据明确标记缺失。
|
||||||
|
|
||||||
|
这不是一次新脑模拟或参数搜索。不改 gain、刺激、阈值、APL 参数、mask 或通过条件;不以本次 CAL 选择后续最佳参数。任何新的动力学假设须另立协议和目录。表征、独立 seed/新气味、信用分配、隔离功能及全脑功能检查通过之后,才有条件进入真正学习验证。
|
||||||
|
|
||||||
|
## 封存与证据入口
|
||||||
|
|
||||||
|
- [正式 r2 报告](phase4ag-author-apl-r2.md)
|
||||||
|
- [原始最终状态](../../registry/phase4ag-author-apl-r2/evidence/audit/final-status.json)
|
||||||
|
- [CAL 原始汇总](../../registry/phase4ag-author-apl-r2/evidence/calibration/summary.json)
|
||||||
|
- [旧数据完整性](../../registry/phase4ag-author-apl-r2/evidence/regression/old-integrity-after.json)
|
||||||
|
- [旧五组参考回归](../../registry/phase4ag-author-apl-r2/evidence/regression/frozen-five.json)
|
||||||
|
- [新封存校验](../../registry/phase4ag-author-apl-r2/seal-verification.json)
|
||||||
|
- [含来源链接的设计/限制历史快照](phase4ag-design-and-limits.md)
|
||||||
|
- [保留的 v1 执行失败报告](phase4ag-author-apl.md)
|
||||||
|
|
||||||
|
r2 模型 manifest SHA-256:`208c00961b9d895d14ac050bc23fbc18db49d0df1fcf5c20d4c3eaa8e15ff7ff`。
|
||||||
|
|
||||||
|
r2 实验 manifest SHA-256:`21593297c40bee58516d4d7fd16e9d8d20ffdea5f8e0652fa5dd4e903b4d96ee`。
|
||||||
|
|
||||||
|
Git 发布代码、文档及小型证据;完整数组和事件文件仍在服务器实验目录。Git 同步不等于全量异机数据备份。
|
||||||
|
|
||||||
|
## 仓库发布检查
|
||||||
|
|
||||||
|
原仓库 681 项文件校验零差异,仓库审计单元测试通过,暂存内容的数据/密钥/大文件检查通过。标准空白检查发现两个已封存 `oracle_apl.py` 各有一个文件末尾空行;为保留登记字节未做格式改写。仅关闭末尾空行规则并允许标准 CSV CRLF 后,其余空白检查通过。这是格式例外,不是数值容差或科学门槛例外。
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
# Phase4AG: author LIF + frozen legacy graded APL
|
||||||
|
|
||||||
|
Authorized independent hypothesis branch. All old source, raw connectome, signs,
|
||||||
|
W_syn, APL calibration, eligibility-v2 and 14,232-edge mask remain read-only.
|
||||||
|
No learning, gain/threshold changes, new edges, top-K, heldout activity, game or RL.
|
||||||
|
|
||||||
|
Author code provenance is the already archived MIT-licensed
|
||||||
|
https://github.com/philshiu/Drosophila_brain_model at
|
||||||
|
91bdd1e7dcf193f3e7ca5a8933497fcef63b7960; original model.py SHA-256
|
||||||
|
fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e.
|
||||||
|
Associated paper: https://www.nature.com/articles/s41586-024-07763-9.
|
||||||
|
This new MaleCNS/APL combination is not a strict reproduction of that model.
|
||||||
|
|
||||||
|
The declared combination is author float64 LIF plus the exact old float32 graded
|
||||||
|
APL operator after synapses/resets at end. All 5,845 original APL fast out-edges
|
||||||
|
are zeroed only in the effective in-memory model, as in the legacy overlay.
|
||||||
|
Only KC receives graded replacement; known 1,212 non-KC edges remain unreplaced.
|
||||||
|
This existing scope limitation is not silently repaired in a compatibility test.
|
||||||
|
|
||||||
|
Use the original full normalized I[2,166700]/O[2,4064] float32 bytes and original
|
||||||
|
normalizers, even for induced real subgraphs. APL reads actual binary spikes,
|
||||||
|
never requests, and keeps independent float32 state. Preserve unfused operations:
|
||||||
|
state.mul_(float(f32(exp(-.1/20)))).add_(torch.mv(I, spikes_f32));
|
||||||
|
h32=torch.matmul(state,O)*f32(.01). Promote h32 to float64, multiply by float64
|
||||||
|
.001, then separately subtract from SI g. Do not alter TF32/default CuBLAS flags;
|
||||||
|
record them. No added APL delay, drive dt/tau scaling, truncation or clipping.
|
||||||
|
|
||||||
|
APL writes KC g unconditionally after author reset, including refractory KC.
|
||||||
|
Author g integration is frozen during refractory; therefore negative overlay g
|
||||||
|
may accumulate and differs from old dynamics. This is an explicit hypothesis,
|
||||||
|
not an assertion of original author or measured physiology. Guarded writes or
|
||||||
|
reset-before/after changes would be different hypotheses, not fixes to this one.
|
||||||
|
|
||||||
|
Eight fixed metadata/connectivity-selected fixtures cover zero/reset, real PN/KC
|
||||||
|
drive, current actual event feedback, duplicate natural/request event, 18-step
|
||||||
|
arrival vs22-step refractory boundary, full fast APL mask, non-KC scope and mixed
|
||||||
|
precision/high fan-in. No choice is made from runtime responses. Each GPU case
|
||||||
|
has3 independent fresh runs. A Brian2 author oracle starts from its own state,
|
||||||
|
computes its own actual spikes, and uses an isolated standard-I/O legacy-APL
|
||||||
|
worker with independent state. No candidate inhibition trace is fed into Brian.
|
||||||
|
All tick states, events, requests, queue order/guard, APL drive/state/h must agree
|
||||||
|
exactly. The APL component is shared, so this is NOT a fully independent CPU
|
||||||
|
oracle. Independently reconstruct old matrices using frozen initializer AST,
|
||||||
|
replay actual events through original update AST, require exact component bytes;
|
||||||
|
also quantify an independent float64 positive-sum arithmetic error bound. It is
|
||||||
|
not a replacement for exact legacy equivalence. No arithmetic bound is adjusted.
|
||||||
|
|
||||||
|
Only after all fixture gates pass, run two predeclared full-graph probes: first
|
||||||
|
old calibration odor, first original seed, both encoder modes. Compare each with
|
||||||
|
the independently running Brian + isolated APL worker. Save state hashes and sparse
|
||||||
|
events, not a time-by-all-neurons dense spike matrix. If a numerical gate fails,
|
||||||
|
stop CAL; keep diagnostic evidence and do not widen tolerance.
|
||||||
|
|
||||||
|
Then run the complete original6 CAL odors ×5 original seeds ×2 original modes,
|
||||||
|
100ms per run. Retain the ORIGINAL12-odor median for matched-energy encoding,
|
||||||
|
original pn_drive target/RNG column order, original evaluation seeds51101..51105.
|
||||||
|
Save Poisson requests before any trajectory. Only calibration dynamic cases are
|
||||||
|
used; formal A/B and heldout remain unrun. Repeat first seed for every odor/mode.
|
||||||
|
No per-odor pulse, amplitude, timing or threshold search. No learning.
|
||||||
|
|
||||||
|
Recompute the full original4L representation criteria on CAL only: mean KC active
|
||||||
|
fraction .03..09, min>0, max<.5, same-odor Jaccard>different, between Euclidean>
|
||||||
|
within, >=3 pairs whose mean between exceeds THAT PAIR's pooled within distances,
|
||||||
|
both modes. Add finiteness and exact repeat requirements. CAL PASS does not imply
|
||||||
|
heldout generalization, timing/credit specificity, memory or learning usability.
|
||||||
|
If CAL fails stop promotion and report it, not a least-bad candidate.
|
||||||
|
|
||||||
|
Before/after verify SHA-256 of all original230239 files and AA--AF seals; rerun original five
|
||||||
|
deterministic reference trials to new output. Archive code/env/source SHA,
|
||||||
|
matrices/norms/masks/identities, requests and all outputs. No published candidate.
|
||||||
|
|
||||||
|
Technical references (queried2026-09-30): Brian2 2.5.1 refractory documentation
|
||||||
|
https://brian2.readthedocs.io/en/2.5.1/user/refractoriness.html (actual generated code
|
||||||
|
remains authoritative); PyTorch numerical accuracy notes
|
||||||
|
https://docs.pytorch.org/docs/2.14/notes/numerical_accuracy.html (cross-backend
|
||||||
|
floating operations are not assumed bitwise equivalent).
|
||||||
@@ -0,0 +1,396 @@
|
|||||||
|
"""Complete original Phase 4L representation metrics on fixed CAL inputs only.
|
||||||
|
|
||||||
|
No simulation, fitting, heldout trajectory access, or candidate generation is
|
||||||
|
performed here. The original 4L pair-specific within-odor baseline is retained;
|
||||||
|
the weaker Phase 4P r4 aggregate gate is deliberately not used.
|
||||||
|
"""
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import itertools
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
STATE_DTYPES = {"step": np.int32, "neuron_idx": np.int32, "counts": np.int32,
|
||||||
|
"v": np.float64, "g": np.float64, "ref": np.int32}
|
||||||
|
REQUEST_FIELDS = ("tick", "neuron_idx", "attempted", "accepted", "rejected")
|
||||||
|
APL_FILES = {"apl-drive.float32.npy": 2, "apl-state.float32.npy": 2,
|
||||||
|
"apl-inhibition.float32.npy": 4064}
|
||||||
|
ORIGINAL_CAL_IDS = {
|
||||||
|
"OMSUIQOIVADKIM-RXMQYKEDSA-N", "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"QNVRIHYSUZMSGM-ZCFIWIBFSA-N", "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"XHIUFYZDQBSEMF-UHFFFAOYSA-N", "OMSUIQOIVADKIM-YFKPBYRVSA-N"}
|
||||||
|
ORIGINAL_MODES = ("physiological", "matched_energy")
|
||||||
|
ORIGINAL_SEEDS = (51101, 51102, 51103, 51104, 51105)
|
||||||
|
HEX_SHA = re.compile(r"[0-9a-f]{64}\Z")
|
||||||
|
_DEFAULT_OUTPUT = object()
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def read_json(path):
|
||||||
|
with Path(path).open(encoding="utf-8") as stream:
|
||||||
|
return json.load(stream)
|
||||||
|
|
||||||
|
|
||||||
|
def file_hash(path):
|
||||||
|
digest = hashlib.sha256()
|
||||||
|
with Path(path).open("rb") as stream:
|
||||||
|
for block in iter(lambda: stream.read(8 << 20), b""):
|
||||||
|
digest.update(block)
|
||||||
|
return digest.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def raw_hash(value):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def arrays_bitwise_equal(first, second):
|
||||||
|
"""Unlike array_equal, also reject different dtypes and signed-zero bits."""
|
||||||
|
return bool(first.dtype == second.dtype and first.shape == second.shape and
|
||||||
|
np.array_equal(np.ascontiguousarray(first).view(np.uint8),
|
||||||
|
np.ascontiguousarray(second).view(np.uint8)))
|
||||||
|
|
||||||
|
|
||||||
|
def pair_metrics(a, b):
|
||||||
|
"""Exact definitions copied from phase4i.pair_metrics/safe_corr/cosine."""
|
||||||
|
x, y = a.astype(np.float64), b.astype(np.float64)
|
||||||
|
aa, bb = a > 0, b > 0
|
||||||
|
union = int(np.count_nonzero(aa | bb))
|
||||||
|
intersection = int(np.count_nonzero(aa & bb))
|
||||||
|
denominator = float(np.linalg.norm(x) * np.linalg.norm(y))
|
||||||
|
cosine = 1.0 if denominator == 0 and np.array_equal(x, y) else (
|
||||||
|
0.0 if denominator == 0 else float(np.dot(x, y) / denominator))
|
||||||
|
correlation = (1.0 if np.array_equal(x, y) else 0.0) if np.std(x) == 0 or np.std(y) == 0 else float(np.corrcoef(x, y)[0, 1])
|
||||||
|
return {"active_intersection": intersection, "active_union": union,
|
||||||
|
"active_jaccard": 1.0 if union == 0 else float(intersection / union),
|
||||||
|
"cosine_similarity": cosine, "correlation": correlation,
|
||||||
|
"euclidean_distance": float(np.linalg.norm(x - y))}
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate_gates(summary, gates):
|
||||||
|
"""Each conjunct in original phase4l.py:239, kept visible for audit."""
|
||||||
|
return {
|
||||||
|
"mean_sparsity_in_closed_interval": bool(float(gates["sparse_min_fraction"]) <=
|
||||||
|
summary["KC_active_fraction_mean"] <= float(gates["sparse_max_fraction"])),
|
||||||
|
"maximum_strictly_below_half": bool(summary["KC_active_fraction_max"] < 0.5),
|
||||||
|
"minimum_strictly_positive": bool(summary["KC_active_fraction_min"] > 0),
|
||||||
|
"same_jaccard_gt_different": bool(summary["same_odor_jaccard_mean"] > summary["different_odor_jaccard_mean"]),
|
||||||
|
"different_euclidean_gt_same": bool(summary["different_odor_euclidean_mean"] > summary["same_odor_euclidean_mean"]),
|
||||||
|
"at_least_original_pair_count": bool(summary["pairwise_separation_pass_count"] >= int(gates["minimum_separable_odor_pairs"]))}
|
||||||
|
|
||||||
|
|
||||||
|
def sample_cv(values):
|
||||||
|
"""Original pandas Series.std uses ddof=1. Undefined diagnostic -> null."""
|
||||||
|
values = np.asarray(values, dtype=np.float64)
|
||||||
|
mean = float(values.mean())
|
||||||
|
return None if mean == 0 else float(values.std(ddof=1) / mean)
|
||||||
|
|
||||||
|
|
||||||
|
def summarize_mode(mode, odor_ids, seeds, runs, gates):
|
||||||
|
within, within_j, between, between_j, between_cos, between_corr = [], [], [], [], [], []
|
||||||
|
pairs = []
|
||||||
|
for odor in odor_ids:
|
||||||
|
arrays = [runs[(mode, odor, seed)]["kc_counts"] for seed in seeds]
|
||||||
|
for first, second in itertools.combinations(arrays, 2):
|
||||||
|
metric = pair_metrics(first, second)
|
||||||
|
within.append(metric["euclidean_distance"])
|
||||||
|
within_j.append(metric["active_jaccard"])
|
||||||
|
for first_odor, second_odor in itertools.combinations(odor_ids, 2):
|
||||||
|
distances = []
|
||||||
|
for seed in seeds:
|
||||||
|
metric = pair_metrics(runs[(mode, first_odor, seed)]["kc_counts"],
|
||||||
|
runs[(mode, second_odor, seed)]["kc_counts"])
|
||||||
|
distances.append(metric["euclidean_distance"])
|
||||||
|
between.append(metric["euclidean_distance"])
|
||||||
|
between_j.append(metric["active_jaccard"])
|
||||||
|
between_cos.append(metric["cosine_similarity"])
|
||||||
|
between_corr.append(metric["correlation"])
|
||||||
|
pair_within = []
|
||||||
|
for odor in (first_odor, second_odor):
|
||||||
|
arrays = [runs[(mode, odor, seed)]["kc_counts"] for seed in seeds]
|
||||||
|
pair_within.extend(pair_metrics(first, second)["euclidean_distance"]
|
||||||
|
for first, second in itertools.combinations(arrays, 2))
|
||||||
|
cross_mean, within_mean = float(np.mean(distances)), float(np.mean(pair_within))
|
||||||
|
pairs.append({"odor_id_a": first_odor, "odor_id_b": second_odor,
|
||||||
|
"between_same_seed_mean": cross_mean, "within_this_pair_mean": within_mean,
|
||||||
|
"between_distance_count": len(distances), "within_distance_count": len(pair_within),
|
||||||
|
"gate": bool(cross_mean > within_mean)})
|
||||||
|
selected = [runs[(mode, odor, seed)] for odor in odor_ids for seed in seeds]
|
||||||
|
fractions = [int(np.count_nonzero(run["kc_counts"])) / len(run["kc_counts"]) for run in selected]
|
||||||
|
summary = {"KC_active_fraction_mean": float(np.mean(fractions)),
|
||||||
|
"KC_active_fraction_min": float(np.min(fractions)), "KC_active_fraction_max": float(np.max(fractions)),
|
||||||
|
"same_odor_jaccard_mean": float(np.mean(within_j)),
|
||||||
|
"different_odor_jaccard_mean": float(np.mean(between_j)),
|
||||||
|
"same_odor_euclidean_mean": float(np.mean(within)),
|
||||||
|
"different_odor_euclidean_mean": float(np.mean(between)),
|
||||||
|
"different_odor_cosine_mean": float(np.mean(between_cos)),
|
||||||
|
"different_odor_correlation_mean": float(np.mean(between_corr)),
|
||||||
|
"within_variance": float(np.var(within)), "between_distance_mean": float(np.mean(between)),
|
||||||
|
"pairwise_separation_pass_count": sum(row["gate"] for row in pairs), "pair_count": len(pairs),
|
||||||
|
"expected_event_count_cv": sample_cv([run["expected_external_events"] for run in selected]),
|
||||||
|
"actual_event_count_cv": sample_cv([run["external_events"] for run in selected]),
|
||||||
|
"within_distance_count": len(within), "between_distance_count": len(between),
|
||||||
|
"pairwise_baseline": "Each pair's two odors: 10+10 within-seed distances; never pooled across all odors",
|
||||||
|
"pairs": pairs}
|
||||||
|
summary["conditions"] = evaluate_gates(summary, gates)
|
||||||
|
summary["gate"] = bool(all(summary["conditions"].values()))
|
||||||
|
return summary
|
||||||
|
|
||||||
|
|
||||||
|
def validate_state(state, neurons, steps):
|
||||||
|
require(set(state) == set(STATE_DTYPES), "state.npz must have exactly the six declared arrays")
|
||||||
|
for name, dtype in STATE_DTYPES.items():
|
||||||
|
value = state[name]
|
||||||
|
require(value.dtype == dtype and value.ndim == 1, "Invalid state dtype/rank: " + name)
|
||||||
|
require(bool(np.isfinite(value).all()), "Nonfinite state: " + name)
|
||||||
|
if name not in ("step", "neuron_idx"):
|
||||||
|
require(value.shape == (neurons,), "Invalid state length: " + name)
|
||||||
|
ticks, nodes = state["step"], state["neuron_idx"]
|
||||||
|
require(ticks.shape == nodes.shape and bool(np.all((ticks >= 0) & (ticks < steps))) and
|
||||||
|
bool(np.all((nodes >= 0) & (nodes < neurons))), "Invalid sparse event indices")
|
||||||
|
keys = ticks.astype(np.int64) * neurons + nodes
|
||||||
|
require(bool(np.all(np.diff(keys) > 0)), "Sparse events not sorted unique by tick/global neuron")
|
||||||
|
require(np.array_equal(np.bincount(nodes, minlength=neurons), state["counts"]), "Counts disagree with sparse events")
|
||||||
|
require(bool(np.all((state["ref"] >= 0) & (state["ref"] <= 22))), "Final refractory outside frozen range")
|
||||||
|
return keys
|
||||||
|
|
||||||
|
|
||||||
|
def read_jsonl(path, steps, kind):
|
||||||
|
with Path(path).open(encoding="utf-8") as source:
|
||||||
|
rows = [json.loads(line) for line in source if line.strip()]
|
||||||
|
require(len(rows) == steps and [row.get("tick") for row in rows] == list(range(steps)),
|
||||||
|
"Missing/duplicate/reordered ticks in " + kind)
|
||||||
|
for row in rows:
|
||||||
|
names = ("v_sha256", "g_sha256", "ref_sha256") if kind == "state hashes" else (
|
||||||
|
"ordered_edge_sha256", "accepted_mask_sha256", "joint_sha256")
|
||||||
|
for name in names:
|
||||||
|
require(isinstance(row.get(name), str) and HEX_SHA.fullmatch(row[name]), "Invalid SHA256 in " + kind)
|
||||||
|
if kind == "queue":
|
||||||
|
require(type(row.get("count")) is int and type(row.get("accepted_count")) is int and
|
||||||
|
0 <= row["accepted_count"] <= row["count"], "Invalid queue counts")
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def read_trial(output, case, spec, kc_globals, neurons, edges):
|
||||||
|
summary = read_json(output / "summary.json")
|
||||||
|
steps = spec["steps"]
|
||||||
|
require(summary.get("complete") is True and summary.get("pass_all") is True and
|
||||||
|
summary.get("all_finite") is True and summary.get("steps") == steps and
|
||||||
|
summary.get("completed_ticks") == steps and summary.get("nodes") == neurons and
|
||||||
|
summary.get("edges") == edges and summary.get("precision") == "float64" and
|
||||||
|
summary.get("apl_precision") == "float32" and summary.get("case") == spec["name"] and
|
||||||
|
summary.get("record_history") is False and summary.get("learning") is False,
|
||||||
|
"Incomplete/failed/wrong-scope GPU summary")
|
||||||
|
with np.load(output / "state.npz", allow_pickle=False) as source:
|
||||||
|
state = {name: source[name].copy() for name in source.files}
|
||||||
|
event_keys = validate_state(state, neurons, steps)
|
||||||
|
hashes = read_jsonl(output / "tick-state-hashes.jsonl", steps, "state hashes")
|
||||||
|
for name in ("v", "g", "ref"):
|
||||||
|
require(hashes[-1][name + "_sha256"] == raw_hash(state[name]), "Final state does not match last tick hash: " + name)
|
||||||
|
queues = read_jsonl(output / "queue.jsonl", steps, "queue")
|
||||||
|
apl = {}
|
||||||
|
for name, width in APL_FILES.items():
|
||||||
|
value = np.load(output / name, mmap_mode="r", allow_pickle=False)
|
||||||
|
require(value.dtype == np.float32 and value.shape == (steps, width) and
|
||||||
|
bool(np.isfinite(value).all()) and bool(np.all(value >= 0)), "Invalid full APL trace: " + name)
|
||||||
|
apl[name] = value
|
||||||
|
with (output / "requests.csv").open(encoding="utf-8", newline="") as source:
|
||||||
|
reader = csv.DictReader(source)
|
||||||
|
require(tuple(reader.fieldnames or ()) == REQUEST_FIELDS, "Request CSV schema mismatch")
|
||||||
|
request_rows = [{name: int(row[name]) for name in REQUEST_FIELDS} for row in reader]
|
||||||
|
with np.load(case / "requests.npz", allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == {"tick", "neuron_idx"}, "Input request schema mismatch")
|
||||||
|
expected_ticks, expected_nodes = source["tick"], source["neuron_idx"]
|
||||||
|
require(expected_ticks.dtype == np.int32 and expected_nodes.dtype == np.int32 and
|
||||||
|
expected_ticks.ndim == 1 and expected_ticks.shape == expected_nodes.shape,
|
||||||
|
"Input request dtype/shape mismatch")
|
||||||
|
require(len(request_rows) == len(expected_ticks), "Requested event coverage mismatch")
|
||||||
|
require([row["tick"] for row in request_rows] == expected_ticks.tolist() and
|
||||||
|
[row["neuron_idx"] for row in request_rows] == expected_nodes.tolist(), "Requests differ from frozen input")
|
||||||
|
require(all(row["attempted"] == 1 and row["accepted"] in (0, 1) and
|
||||||
|
row["rejected"] == 1 - row["accepted"] for row in request_rows), "Invalid request acceptance bookkeeping")
|
||||||
|
requested_keys = expected_ticks.astype(np.int64) * neurons + expected_nodes
|
||||||
|
require(bool(np.all(np.diff(requested_keys) > 0)) and bool(np.all((expected_ticks >= 0) & (expected_ticks < steps))) and
|
||||||
|
bool(np.all((expected_nodes >= 0) & (expected_nodes < neurons))), "Input requests not sorted unique/in range")
|
||||||
|
actual_accepted = np.array([row["accepted"] for row in request_rows], dtype=np.uint8)
|
||||||
|
require(np.array_equal(np.isin(requested_keys, event_keys, assume_unique=True), actual_accepted.astype(bool)),
|
||||||
|
"Request accepted/rejected values disagree with actual spikes")
|
||||||
|
accepted = int(actual_accepted.sum())
|
||||||
|
require(summary.get("requested") == len(request_rows) and summary.get("accepted_requests") == accepted and
|
||||||
|
summary.get("rejected_requests") == len(request_rows) - accepted and
|
||||||
|
summary.get("total_spikes") == len(state["step"]), "Summary counts disagree with raw output")
|
||||||
|
component = read_json(output / "apl-component.json")
|
||||||
|
require(component.get("ok") is True and component.get("n_neurons") == neurons and
|
||||||
|
component.get("n_kc") == len(kc_globals) and component.get("n_apl") == 2 and
|
||||||
|
component.get("dt_ms") == .1 and summary.get("apl_component") == component,
|
||||||
|
"APL component provenance mismatch")
|
||||||
|
bundle = Path(spec["apl_bundle_dir"])
|
||||||
|
require(component.get("files_sha256") == {name: file_hash(bundle / name) for name in
|
||||||
|
("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")}, "APL bundle hashes changed")
|
||||||
|
inputs = summary.get("input_sha256", {})
|
||||||
|
require(inputs.get("spec.json") == file_hash(case / "spec.json") and
|
||||||
|
inputs.get("requests.npz") == file_hash(case / "requests.npz"), "Case input provenance mismatch")
|
||||||
|
kc_counts = state["counts"][kc_globals].copy()
|
||||||
|
kc_event_mask = np.isin(state["neuron_idx"], kc_globals)
|
||||||
|
record = {"case": spec["name"], "mode": spec["mode"], "odor_id": spec["odor_id"],
|
||||||
|
"odor_name": spec["odor_name"], "seed": spec["seed"], "split": "calibration",
|
||||||
|
"KC_active": int(np.count_nonzero(kc_counts)), "KC_active_fraction": float(np.count_nonzero(kc_counts) / len(kc_globals)),
|
||||||
|
"KC_spikes": int(kc_counts.sum()), "KC_first_latency_ms":
|
||||||
|
float(state["step"][kc_event_mask][0] * .1) if bool(np.any(kc_event_mask)) else None,
|
||||||
|
"external_events": accepted, "expected_external_events": float(spec["expected_external_events"]),
|
||||||
|
"total_PN_rate_hz": float(spec["rate_sum_hz"]), "finite": True,
|
||||||
|
"total_spikes": len(state["step"]), "requested": len(request_rows)}
|
||||||
|
require(np.isfinite(record["expected_external_events"]) and record["expected_external_events"] > 0,
|
||||||
|
"CAL expected external events must be finite and positive")
|
||||||
|
return {"state": state, "hashes": hashes, "queues": queues, "apl": apl,
|
||||||
|
"requests": request_rows, "component": component, "kc_counts": kc_counts,
|
||||||
|
"expected_external_events": record["expected_external_events"], "external_events": accepted,
|
||||||
|
"record": record, "output": output}
|
||||||
|
|
||||||
|
|
||||||
|
def exact_repeat(first, repeat):
|
||||||
|
checks = {"state/" + name: arrays_bitwise_equal(first["state"][name], repeat["state"][name]) for name in STATE_DTYPES}
|
||||||
|
checks.update({name: arrays_bitwise_equal(first["apl"][name], repeat["apl"][name]) for name in APL_FILES})
|
||||||
|
checks.update(tick_state_hashes=first["hashes"] == repeat["hashes"],
|
||||||
|
queues=first["queues"] == repeat["queues"], requests=first["requests"] == repeat["requests"],
|
||||||
|
apl_component=first["component"] == repeat["component"])
|
||||||
|
return {"pass_all": bool(all(checks.values())), "checks": checks,
|
||||||
|
"scope": "All six state arrays, every tick all-neuron hashes, APL raw float32 traces, queues, requests and APL environment"}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_inventory(records, cfg):
|
||||||
|
require(tuple(cfg["calibration"]["modes"]) == ORIGINAL_MODES and
|
||||||
|
tuple(cfg["calibration"]["seeds"]) == ORIGINAL_SEEDS and
|
||||||
|
cfg["calibration"]["duration_ms"] == 100.0 and cfg["calibration"]["odor_count"] == 6 and
|
||||||
|
cfg["calibration"]["split"] == "calibration" and
|
||||||
|
cfg["calibration"]["repeat_first_seed_each_odor"] is True, "Frozen CAL design changed")
|
||||||
|
gates = cfg["gates"]
|
||||||
|
require(gates["sparse_min_fraction"] == .03 and gates["sparse_max_fraction"] == .09 and
|
||||||
|
gates["minimum_separable_odor_pairs"] == 3 and gates["max_fraction_strict"] == .5 and
|
||||||
|
gates["min_fraction_strict"] == 0 and all(gates[key] is True for key in
|
||||||
|
("same_jaccard_gt_between", "between_euclidean_gt_within", "both_modes_required", "finite_required", "repeat_exact_required")),
|
||||||
|
"Original representation gates or additional integrity gates changed")
|
||||||
|
expected = {(mode, index, seed) for mode in ORIGINAL_MODES for index in range(6) for seed in ORIGINAL_SEEDS}
|
||||||
|
require(len(records) == 60 and {(row["mode"], row["odor_index"], row["seed"]) for row in records} == expected,
|
||||||
|
"CAL inventory must cover exactly 2 modes x 6 odors x 5 seeds")
|
||||||
|
odors = []
|
||||||
|
for index in range(6):
|
||||||
|
ids = {row["odor_id"] for row in records if row["odor_index"] == index}
|
||||||
|
require(len(ids) == 1, "Odor identity changes across seeds/modes")
|
||||||
|
odors.append(next(iter(ids)))
|
||||||
|
require(set(odors) == ORIGINAL_CAL_IDS, "CAL identities differ from the original frozen six")
|
||||||
|
for row in records:
|
||||||
|
require(row["name"] == f"cal-{row['mode']}-{row['odor_index']:02d}-s{row['seed']}", "Unexpected CAL case name")
|
||||||
|
return odors
|
||||||
|
|
||||||
|
|
||||||
|
def summarize(out_json=_DEFAULT_OUTPUT):
|
||||||
|
"""Recompute; default writes exclusively, out_json=None is strictly read-only."""
|
||||||
|
from context import EXP, ROOT, CFG, check
|
||||||
|
target = EXP / "calibration/summary.json" if out_json is _DEFAULT_OUTPUT else (
|
||||||
|
None if out_json is None else Path(out_json))
|
||||||
|
require(target is None or not target.exists(), "Refusing existing calibration summary")
|
||||||
|
failures, runs, run_records, repeats, provenance = [], {}, [], [], []
|
||||||
|
modes, odors = {}, []
|
||||||
|
prerequisites_ok = False
|
||||||
|
encoder = None
|
||||||
|
records = []
|
||||||
|
try:
|
||||||
|
check()
|
||||||
|
records = read_json(EXP / "protocol/calibration-cases.json")
|
||||||
|
odors = validate_inventory(records, CFG)
|
||||||
|
encoder = read_json(EXP / "protocol/encoder-audit.json")
|
||||||
|
require(encoder["panel_count"] == 12 and encoder["cal_count"] == 6 and
|
||||||
|
encoder["seeds"] == list(ORIGINAL_SEEDS) and encoder["requested_before_any_dynamics"] is True and
|
||||||
|
encoder["formal_AB_run"] is False and encoder["heldout_run"] is False, "Invalid frozen encoder scope")
|
||||||
|
# Only static original-panel metadata is read, never heldout trajectories.
|
||||||
|
import pandas as pd
|
||||||
|
original = pd.read_parquet(ROOT / "experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet")
|
||||||
|
require(len(original) == 12 and set(original[original.split == "calibration"].odor_id) == ORIGINAL_CAL_IDS,
|
||||||
|
"Original static panel identity mismatch")
|
||||||
|
require(float(np.median(original.mapped_response_sum)) == encoder["median_mapped_response_sum"],
|
||||||
|
"Matched-energy reference is not the original frozen 12-panel median")
|
||||||
|
kc_globals = np.load(EXP / "apl-bundle/kc_globals.npy", allow_pickle=False)
|
||||||
|
require(kc_globals.dtype == np.int32 and kc_globals.shape == (4064,) and
|
||||||
|
bool(np.all(np.diff(kc_globals) > 0)) and bool(np.all((kc_globals >= 0) & (kc_globals < CFG["neurons"]))),
|
||||||
|
"Invalid frozen KC identities")
|
||||||
|
prerequisites_ok = True
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "prerequisites", "type": type(error).__name__, "message": str(error)})
|
||||||
|
if prerequisites_ok:
|
||||||
|
for row in records:
|
||||||
|
name = row["name"]
|
||||||
|
first = None
|
||||||
|
try:
|
||||||
|
case = EXP / "cases" / name
|
||||||
|
spec = read_json(case / "spec.json")
|
||||||
|
require(spec["name"] == name and spec["kind"] == "calibration" and spec["steps"] == 1000 and
|
||||||
|
spec["duration_ms"] == 100.0 and spec["dt_ms"] == .1 and spec["training"] is False and
|
||||||
|
all(spec[key] == row[key] for key in ("mode", "odor_id", "odor_index", "seed")),
|
||||||
|
"Case spec differs from fixed CAL inventory")
|
||||||
|
first = read_trial(EXP / "gpu" / (name + "-r0"), case, spec, kc_globals, CFG["neurons"], CFG["edges"])
|
||||||
|
require(first["record"]["requested"] == row["requests"], "Frozen inventory request count mismatch")
|
||||||
|
runs[(row["mode"], row["odor_id"], row["seed"])] = {key: first[key] for key in
|
||||||
|
("kc_counts", "expected_external_events", "external_events")}
|
||||||
|
run_records.append(first["record"])
|
||||||
|
provenance.append({"case": name, "repeat": 0, "state_npz_sha256": file_hash(first["output"] / "state.npz"),
|
||||||
|
"summary_sha256": file_hash(first["output"] / "summary.json")})
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "raw_trial", "case": name, "repeat": 0,
|
||||||
|
"type": type(error).__name__, "message": str(error)})
|
||||||
|
if row["seed"] == ORIGINAL_SEEDS[0]:
|
||||||
|
try:
|
||||||
|
require(first is not None, "Baseline unavailable for exact repeat")
|
||||||
|
repeat = read_trial(EXP / "gpu" / (name + "-r1"), case, spec, kc_globals, CFG["neurons"], CFG["edges"])
|
||||||
|
repeat_report = {"case": name, **exact_repeat(first, repeat)}
|
||||||
|
repeats.append(repeat_report)
|
||||||
|
provenance.append({"case": name, "repeat": 1, "state_npz_sha256": file_hash(repeat["output"] / "state.npz"),
|
||||||
|
"summary_sha256": file_hash(repeat["output"] / "summary.json")})
|
||||||
|
require(repeat_report["pass_all"], "Exact repeat differs: " + ", ".join(
|
||||||
|
key for key, value in repeat_report["checks"].items() if not value))
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "exact_repeat", "case": name, "repeat": 1,
|
||||||
|
"type": type(error).__name__, "message": str(error)})
|
||||||
|
if len(runs) == 60:
|
||||||
|
for mode in ORIGINAL_MODES:
|
||||||
|
try:
|
||||||
|
modes[mode] = summarize_mode(mode, odors, ORIGINAL_SEEDS, runs, CFG["gates"])
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "representation", "mode": mode,
|
||||||
|
"type": type(error).__name__, "message": str(error)})
|
||||||
|
integrity_pass = bool(prerequisites_ok and len(runs) == 60 and not any(row["stage"] in
|
||||||
|
("prerequisites", "raw_trial") for row in failures))
|
||||||
|
repeat_pass = bool(len(repeats) == 12 and all(row["pass_all"] for row in repeats) and
|
||||||
|
not any(row["stage"] == "exact_repeat" for row in failures))
|
||||||
|
representation_pass = bool(len(modes) == 2 and all(row["gate"] for row in modes.values()))
|
||||||
|
result = {"phase": "4AG", "scope": "Original fixed six CAL odors only; not heldout generalization or learning",
|
||||||
|
"pass_all": bool(integrity_pass and repeat_pass and representation_pass),
|
||||||
|
"numerical_integrity_pass": integrity_pass, "exact_repeat_pass": repeat_pass,
|
||||||
|
"original_representation_gate_pass": representation_pass,
|
||||||
|
"expected_base_trials": 60, "valid_base_trials": len(runs), "expected_repeats": 12,
|
||||||
|
"checked_repeats": len(repeats), "seeds": list(ORIGINAL_SEEDS), "duration_ms": 100.0,
|
||||||
|
"odor_ids": odors, "modes": modes, "runs": run_records, "repeats": repeats,
|
||||||
|
"failures": failures, "input_output_provenance": provenance, "encoder_audit": encoder,
|
||||||
|
"metric_source": "phase4l.representation (full original gate), phase4i.pair_metrics",
|
||||||
|
"finite_gate_note": "Added integrity prerequisite; original 4L recorded finite but omitted it from its gate",
|
||||||
|
"repeat_gate_note": "Additional exact repeat requirement; original metrics and numerical thresholds unchanged",
|
||||||
|
"shared_apl_component_oracle_limit": True, "independent_oracle_equivalence_claim": False,
|
||||||
|
"candidate_generated": False, "training": False, "heldout_dynamic_access": False}
|
||||||
|
if target is not None:
|
||||||
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with target.open("x", encoding="utf-8") as output:
|
||||||
|
json.dump(result, output, ensure_ascii=False, indent=2, allow_nan=False)
|
||||||
|
output.write("\n")
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(json.dumps({key: value for key, value in summarize().items() if key in
|
||||||
|
("pass_all", "numerical_integrity_pass", "exact_repeat_pass", "original_representation_gate_pass")}), flush=True)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
c14c2d3c35e2b404c516befa66370723fba075516540214ae46e4104ff87e813 PROTOCOL.md
|
||||||
|
edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c calibration.py
|
||||||
|
6e1616b086f667fa4e4b5087f500f8080281977ca9922e7b055acfddd2003bd5 compare.py
|
||||||
|
2aa6b4d777ff698018e1a6eaf571215208b8c874a4c848a6d632e2bd778c90e3 config.json
|
||||||
|
b8b1231d958a3ec935ec1d5a36e08cbd9bcd1127f4d4bb243a9051884a0e7a16 context.py
|
||||||
|
b6e3c67e668a971b544df32d76435ab5e537061b9fc2e8d9dedb5d2a726f5782 finalize.py
|
||||||
|
69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a gpu_apl.py
|
||||||
|
21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291 legacy_apl_worker.py
|
||||||
|
9b7f3e0b59f2117b94b41a6f542f37e6f7950138d324c905e8e0ac6cb7d17151 oracle_apl.py
|
||||||
|
197ccc6aae70566c4db4d4de17fa032e853b9bd9a04262905d6c71e12a930b6f prepare.py
|
||||||
|
afbe6d5a37c29bda66d38c470093584130d1852e67881c681662aec3c76b33c7 run_case.py
|
||||||
|
84c681030b0032119b5392d0c3f3c136a9c6b0d133eb548c40791a10bbbb8b63 run_suite.py
|
||||||
|
bab3136eecbc5bb09a985d715844ee845cb72b07930ce376bfb39be33bd1845a test_calibration.py
|
||||||
|
1a233f47943e01bbd845ac1dacdb1eec3f88c270c65a5f75bce1cf679b5de097 test_protocol.py
|
||||||
|
5cfc9a4505da6b8fb4e7d2617cdaedaa8475ed46a11ec9bdf0d4d25b1d22c2d3 validate_components.py
|
||||||
|
0d0e72b2f1348f6648124c8c34f75094f76fc5e1a281fbcca130a5fad2f35293 verify_frozen.py
|
||||||
|
6aa01a937f1f3c6504ee92e847cf7b3a884e88aa4ef37a68b0b7d4e7deed4bf2 manifest.json
|
||||||
@@ -0,0 +1,508 @@
|
|||||||
|
"""Fail-closed byte-exact audit of the shared-APL closed-loop fixtures.
|
||||||
|
|
||||||
|
Comparison is independent of either backend's stored PASS. No tolerance is
|
||||||
|
used, timing fields are never compared, and reports contain no wall timestamp.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import struct
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
N_GLOBAL = 166700
|
||||||
|
STATE_KEYS = ('step', 'neuron_idx', 'counts', 'v', 'g', 'ref')
|
||||||
|
REQUEST_FIELDS = ('tick', 'neuron_idx', 'attempted', 'accepted', 'rejected')
|
||||||
|
HASH_FIELDS = {'tick', 'v_sha256', 'g_sha256', 'ref_sha256'}
|
||||||
|
QUEUE_FIELDS = {'tick', 'count', 'accepted_count', 'ordered_edge_sha256',
|
||||||
|
'accepted_mask_sha256', 'joint_sha256'}
|
||||||
|
BUNDLE_FILES = ('input_matrix.npy', 'output_matrix.npy', 'kc_globals.npy', 'apl_globals.npy')
|
||||||
|
COEFFICIENTS = ('gd', 'c0', 'cg', 'cv', 'threshold', 'reset', 'seed_volt')
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def file_hash(path):
|
||||||
|
h = hashlib.sha256()
|
||||||
|
with Path(path).open('rb') as source:
|
||||||
|
for block in iter(lambda: source.read(8 << 20), b''):
|
||||||
|
h.update(block)
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def raw_hash(array, dtype=None):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(array, dtype=dtype).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def save(path, report):
|
||||||
|
if path is None:
|
||||||
|
return
|
||||||
|
path = Path(path)
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with path.open('x', encoding='utf-8') as target:
|
||||||
|
json.dump(report, target, indent=2, sort_keys=True, allow_nan=False)
|
||||||
|
target.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def _read_json(path, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
return json.loads(Path(path).read_text(encoding='utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
def _read_jsonl(path, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
with Path(path).open(encoding='utf-8') as source:
|
||||||
|
return [json.loads(line) for line in source if line.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
def _read_array(path, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
return np.load(path, mmap_mode='r', allow_pickle=False)
|
||||||
|
|
||||||
|
|
||||||
|
def _check(checks, name, condition):
|
||||||
|
checks[name] = bool(condition)
|
||||||
|
|
||||||
|
|
||||||
|
def _bit_mask(a, b):
|
||||||
|
if a.dtype.kind == 'f':
|
||||||
|
unsigned = np.dtype('uint'+str(a.dtype.itemsize*8))
|
||||||
|
return np.ascontiguousarray(a).view(unsigned) != np.ascontiguousarray(b).view(unsigned)
|
||||||
|
return a != b
|
||||||
|
|
||||||
|
|
||||||
|
def _compare_array(name, a, b, checks, differences, dtype=None, shape=None):
|
||||||
|
a, b = np.asarray(a), np.asarray(b)
|
||||||
|
schema = a.shape == b.shape and a.dtype == b.dtype and \
|
||||||
|
(dtype is None or a.dtype == np.dtype(dtype)) and (shape is None or a.shape == shape)
|
||||||
|
_check(checks, name+'.schema', schema)
|
||||||
|
if not schema:
|
||||||
|
differences[name] = {'left_shape': list(a.shape), 'right_shape': list(b.shape),
|
||||||
|
'left_dtype': str(a.dtype), 'right_dtype': str(b.dtype), 'expected_shape': None if shape is None else list(shape),
|
||||||
|
'expected_dtype': None if dtype is None else str(np.dtype(dtype))}
|
||||||
|
_check(checks, name+'.bitwise_exact', False)
|
||||||
|
return False
|
||||||
|
finite = bool(np.isfinite(a).all() and np.isfinite(b).all())
|
||||||
|
_check(checks, name+'.finite', finite)
|
||||||
|
mask = _bit_mask(a, b)
|
||||||
|
exact = not bool(np.any(mask))
|
||||||
|
_check(checks, name+'.bitwise_exact', exact)
|
||||||
|
if not exact or not finite:
|
||||||
|
flat = np.flatnonzero(mask.ravel())
|
||||||
|
detail = {'mismatching_elements': int(len(flat)),
|
||||||
|
'first_positions': [list(map(int, np.unravel_index(int(index), a.shape))) for index in flat[:5]],
|
||||||
|
'left_nonfinite': int(np.count_nonzero(~np.isfinite(a))),
|
||||||
|
'right_nonfinite': int(np.count_nonzero(~np.isfinite(b)))}
|
||||||
|
if finite and a.size:
|
||||||
|
error = np.abs(a.astype(np.float64)-b.astype(np.float64))
|
||||||
|
detail.update(max_abs_error=float(error.max()), mean_abs_error=float(error.mean()))
|
||||||
|
if a.dtype.kind == 'f' and len(flat):
|
||||||
|
unsigned = np.dtype('uint'+str(a.dtype.itemsize*8))
|
||||||
|
av = np.ascontiguousarray(a).view(unsigned).ravel()
|
||||||
|
bv = np.ascontiguousarray(b).view(unsigned).ravel()
|
||||||
|
detail['first_bit_patterns'] = [{'left': hex(int(av[index])), 'right': hex(int(bv[index]))} for index in flat[:5]]
|
||||||
|
differences[name] = detail
|
||||||
|
return exact and finite
|
||||||
|
|
||||||
|
|
||||||
|
def _sha(value):
|
||||||
|
return isinstance(value, str) and re.fullmatch('[0-9a-f]{64}', value) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _read_requests(path, steps, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
with Path(path).open(encoding='utf-8', newline='') as source:
|
||||||
|
reader = csv.DictReader(source)
|
||||||
|
require(tuple(reader.fieldnames or ()) == REQUEST_FIELDS, 'Request CSV schema mismatch: '+str(path))
|
||||||
|
rows = [{key: int(row[key]) for key in REQUEST_FIELDS} for row in reader]
|
||||||
|
previous = (-1, -1)
|
||||||
|
for row in rows:
|
||||||
|
key = row['tick'], row['neuron_idx']
|
||||||
|
require(previous < key and 0 <= key[0] < steps and 0 <= key[1] < N_GLOBAL,
|
||||||
|
'Request rows must be sorted, unique, and in range: '+str(path))
|
||||||
|
require(row['attempted'] == 1 and row['accepted'] in (0, 1) and row['rejected'] == 1-row['accepted'],
|
||||||
|
'Request accounting is incomplete: '+str(path))
|
||||||
|
previous = key
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def _load_run(directory, role, n, edges, steps, record_history, name, used, checks):
|
||||||
|
directory = Path(directory)
|
||||||
|
summary = _read_json(directory/'summary.json', used)
|
||||||
|
_check(checks, role+'.summary_complete', summary.get('complete') is True and summary.get('pass_all') is True and
|
||||||
|
summary.get('steps') == steps and summary.get('completed_ticks') == steps and
|
||||||
|
summary.get('nodes') == n and summary.get('edges') == edges and summary.get('precision') == 'float64')
|
||||||
|
is_cpu = role == 'cpu'
|
||||||
|
_check(checks, role+'.case_name', summary.get('name' if is_cpu else 'case') == name)
|
||||||
|
_check(checks, role+'.history_mode', summary.get('history_recorded' if is_cpu else 'record_history') is record_history)
|
||||||
|
_check(checks, role+'.apl_precision', summary.get('APL_precision' if is_cpu else 'apl_precision') == 'float32')
|
||||||
|
_check(checks, role+'.no_error_marker', not (directory/'error.json').exists())
|
||||||
|
used.add(directory/'state.npz')
|
||||||
|
with np.load(directory/'state.npz', allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == set(STATE_KEYS), 'State NPZ keys changed: '+str(directory))
|
||||||
|
state = {key: source[key].copy() for key in STATE_KEYS}
|
||||||
|
for key, dtype in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32'), ('counts', 'int32')):
|
||||||
|
require(state[key].shape == (n,) and state[key].dtype == np.dtype(dtype), 'Invalid final '+key+': '+str(directory))
|
||||||
|
require(state['step'].dtype == state['neuron_idx'].dtype == np.int32 and state['step'].ndim == 1 and
|
||||||
|
state['step'].shape == state['neuron_idx'].shape, 'Invalid sparse event schema: '+str(directory))
|
||||||
|
require(bool(np.all((state['step'] >= 0) & (state['step'] < steps))) and
|
||||||
|
bool(np.all((state['neuron_idx'] >= 0) & (state['neuron_idx'] < N_GLOBAL))), 'Sparse event range error')
|
||||||
|
event_keys = state['step'].astype(np.int64)*N_GLOBAL+state['neuron_idx']
|
||||||
|
_check(checks, role+'.events_sorted_unique', len(event_keys) < 2 or np.all(np.diff(event_keys) > 0))
|
||||||
|
_check(checks, role+'.count_nonnegative_total', np.all(state['counts'] >= 0) and int(state['counts'].sum()) == len(event_keys))
|
||||||
|
_check(checks, role+'.ref_range', np.all((state['ref'] >= 0) & (state['ref'] <= 22)))
|
||||||
|
_check(checks, role+'.reported_events', summary.get('spikes' if is_cpu else 'total_spikes') == len(event_keys))
|
||||||
|
hashes = _read_jsonl(directory/'tick-state-hashes.jsonl', used)
|
||||||
|
require(len(hashes) == steps and [row.get('tick') for row in hashes] == list(range(steps)), 'Incomplete tick hash coverage')
|
||||||
|
require(all(set(row) == HASH_FIELDS and all(_sha(row[key]) for key in HASH_FIELDS-{'tick'}) for row in hashes),
|
||||||
|
'Invalid tick state hash schema')
|
||||||
|
queues = _read_jsonl(directory/'queue.jsonl', used)
|
||||||
|
require(len(queues) == steps and [row.get('tick') for row in queues] == list(range(steps)), 'Incomplete queue coverage')
|
||||||
|
require(all(set(row) == QUEUE_FIELDS and type(row['count']) is int and type(row['accepted_count']) is int and
|
||||||
|
0 <= row['accepted_count'] <= row['count'] <= edges and
|
||||||
|
all(_sha(row[key]) for key in QUEUE_FIELDS-{'tick', 'count', 'accepted_count'}) for row in queues),
|
||||||
|
'Invalid queue row schema/count/hash')
|
||||||
|
for key in ('v', 'g', 'ref'):
|
||||||
|
_check(checks, role+'.last_hash_'+key, hashes[-1][key+'_sha256'] == raw_hash(state[key], '<i4' if key == 'ref' else '<f8'))
|
||||||
|
requests = _read_requests(directory/'requests.csv', steps, used)
|
||||||
|
requested, accepted = len(requests), sum(row['accepted'] for row in requests)
|
||||||
|
_check(checks, role+'.request_summary', summary.get('requests' if is_cpu else 'requested') == requested and
|
||||||
|
summary.get('applicable_requests' if is_cpu else 'accepted_requests') == accepted and
|
||||||
|
summary.get('ref_rejected_requests' if is_cpu else 'rejected_requests') == requested-accepted)
|
||||||
|
apl = {field: _read_array(directory/('apl-'+field+'.float32.npy'), used) for field in ('drive', 'state', 'inhibition')}
|
||||||
|
for field, width in (('drive', 2), ('state', 2), ('inhibition', 4064)):
|
||||||
|
require(apl[field].dtype == np.float32 and apl[field].shape == (steps, width), 'Invalid APL '+field+' history schema')
|
||||||
|
_check(checks, role+'.apl_positive_'+field, np.all(apl[field] >= 0))
|
||||||
|
histories, pre = {}, {}
|
||||||
|
for field, dtype in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32')):
|
||||||
|
files = (directory/(field+'-history.'+dtype+'.npy'), directory/('preAPL-'+field+'.'+dtype+'.npy'))
|
||||||
|
if record_history:
|
||||||
|
histories[field], pre[field] = (_read_array(path, used) for path in files)
|
||||||
|
require(all(array.dtype == np.dtype(dtype) and array.shape == (steps, n) for array in (histories[field], pre[field])),
|
||||||
|
'Small pre/post history schema mismatch')
|
||||||
|
_check(checks, role+'.history_hashes_'+field, all(row[field+'_sha256'] == raw_hash(histories[field][tick])
|
||||||
|
for tick, row in enumerate(hashes)))
|
||||||
|
_check(checks, role+'.history_final_'+field, not np.any(_bit_mask(histories[field][-1], state[field])))
|
||||||
|
else:
|
||||||
|
_check(checks, role+'.no_dense_'+field, not any(path.exists() for path in files))
|
||||||
|
if is_cpu:
|
||||||
|
component = _read_json(directory/'apl-worker-handshake.json', used)['handshake']
|
||||||
|
else:
|
||||||
|
component = _read_json(directory/'apl-component.json', used)
|
||||||
|
_check(checks, role+'.component_summary_consistent', summary.get('apl_component') == component)
|
||||||
|
return dict(directory=directory, summary=summary, state=state, hashes=hashes, queues=queues,
|
||||||
|
requests=requests, apl=apl, histories=histories, pre=pre, component=component)
|
||||||
|
|
||||||
|
|
||||||
|
def _pair_outputs(left, right, checks, differences, n, steps, record_history):
|
||||||
|
for field in STATE_KEYS:
|
||||||
|
shape = None if field in ('step', 'neuron_idx') else (n,)
|
||||||
|
dtype = 'float64' if field in ('v', 'g') else 'int32'
|
||||||
|
_compare_array('state.'+field, left['state'][field], right['state'][field], checks, differences, dtype, shape)
|
||||||
|
for field, width in (('drive', 2), ('state', 2), ('inhibition', 4064)):
|
||||||
|
_compare_array('apl.'+field, left['apl'][field], right['apl'][field], checks, differences, 'float32', (steps, width))
|
||||||
|
for field in ('hashes', 'queues', 'requests', 'component'):
|
||||||
|
same = left[field] == right[field]
|
||||||
|
_check(checks, field+'.parsed_exact', same)
|
||||||
|
if not same:
|
||||||
|
if isinstance(left[field], list):
|
||||||
|
first = next((i for i, (a, b) in enumerate(zip(left[field], right[field])) if a != b), None)
|
||||||
|
differences[field] = {'left_count': len(left[field]), 'right_count': len(right[field]),
|
||||||
|
'first_differing_row': first,
|
||||||
|
'left_row': None if first is None else left[field][first],
|
||||||
|
'right_row': None if first is None else right[field][first]}
|
||||||
|
else:
|
||||||
|
differences[field] = {'left': left[field], 'right': right[field]}
|
||||||
|
if record_history:
|
||||||
|
for stage in ('histories', 'pre'):
|
||||||
|
for field, dtype in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32')):
|
||||||
|
_compare_array(stage+'.'+field, left[stage][field], right[stage][field], checks, differences, dtype, (steps, n))
|
||||||
|
|
||||||
|
|
||||||
|
def _queue_digest(tick, ids, accepted):
|
||||||
|
ids = np.ascontiguousarray(ids, dtype='<i8').tobytes()
|
||||||
|
mask = np.ascontiguousarray(accepted, dtype=np.uint8).tobytes()
|
||||||
|
return {'tick': tick, 'count': len(mask), 'accepted_count': int(np.count_nonzero(accepted)),
|
||||||
|
'ordered_edge_sha256': hashlib.sha256(ids).hexdigest(),
|
||||||
|
'accepted_mask_sha256': hashlib.sha256(mask).hexdigest(),
|
||||||
|
'joint_sha256': hashlib.sha256(b'phase4af-queue-v1\0'+struct.pack('<qq', tick, len(mask))+ids+mask).hexdigest()}
|
||||||
|
|
||||||
|
|
||||||
|
def _independent_event_accounting(run, role, graph, requested, steps, checks, differences):
|
||||||
|
nodes, ptr = graph['nodes'], graph['ptr']
|
||||||
|
n = len(nodes)
|
||||||
|
state = run['state']
|
||||||
|
local = np.searchsorted(nodes, state['neuron_idx'])
|
||||||
|
require(np.all(local < n) and np.array_equal(nodes[local], state['neuron_idx']), 'Actual spike outside graph identity')
|
||||||
|
_check(checks, role+'.events_per_neuron_counts', np.array_equal(np.bincount(local, minlength=n), state['counts']))
|
||||||
|
actual_request_pairs = [(row['tick'], row['neuron_idx']) for row in run['requests']]
|
||||||
|
_check(checks, role+'.requests_match_frozen_input', actual_request_pairs == requested)
|
||||||
|
require(actual_request_pairs == requested, 'Actual request population/time differs from frozen input')
|
||||||
|
bounds = np.searchsorted(state['step'], np.arange(steps+1))
|
||||||
|
request_ticks = np.asarray([row['tick'] for row in run['requests']], np.int32)
|
||||||
|
rbounds = np.searchsorted(request_ticks, np.arange(steps+1))
|
||||||
|
request_nodes = np.asarray([row['neuron_idx'] for row in run['requests']], np.int32)
|
||||||
|
request_local = np.searchsorted(nodes, request_nodes)
|
||||||
|
require(np.all(request_local < n) and np.array_equal(nodes[request_local], request_nodes), 'Request outside graph')
|
||||||
|
last = np.full(n, -1_000_000_000, np.int64)
|
||||||
|
degrees = np.diff(ptr)
|
||||||
|
expected_counts = np.zeros(steps, np.int64)
|
||||||
|
arrival_tick = state['step'].astype(np.int64)+18
|
||||||
|
valid = arrival_tick < steps
|
||||||
|
np.add.at(expected_counts, arrival_tick[valid], degrees[local[valid]])
|
||||||
|
_check(checks, role+'.delayed_all_edges_count', np.array_equal(expected_counts, [row['count'] for row in run['queues']]))
|
||||||
|
request_ok, delivered_ok, ref_ok, queue_ok, reset_ok = True, True, True, True, True
|
||||||
|
first = {}
|
||||||
|
for tick in range(steps):
|
||||||
|
fired = local[bounds[tick]:bounds[tick+1]]
|
||||||
|
lo, hi = rbounds[tick:tick+2]
|
||||||
|
targets = request_local[lo:hi]
|
||||||
|
accepted = (tick-last[targets]) >= 22
|
||||||
|
for index, ok in zip(range(lo, hi), accepted):
|
||||||
|
row = run['requests'][index]
|
||||||
|
if row['accepted'] != int(ok) or row['rejected'] != int(not ok):
|
||||||
|
request_ok = False
|
||||||
|
first.setdefault('request_ref_mismatch', {'tick': tick, 'neuron_idx': row['neuron_idx']})
|
||||||
|
if not np.isin(targets[accepted], fired).all() or np.isin(targets[~accepted], fired).any():
|
||||||
|
delivered_ok = False
|
||||||
|
first.setdefault('request_delivery_mismatch', tick)
|
||||||
|
last[fired] = tick
|
||||||
|
ref = np.maximum(22-(tick-last), 0).astype(np.int32)
|
||||||
|
if raw_hash(ref, '<i4') != run['hashes'][tick]['ref_sha256']:
|
||||||
|
ref_ok = False
|
||||||
|
first.setdefault('ref_hash_mismatch', tick)
|
||||||
|
if run['pre']:
|
||||||
|
if len(fired) and not np.array_equal(np.ascontiguousarray(run['pre']['g'][tick, fired]).view(np.uint64), np.zeros(len(fired), np.uint64)):
|
||||||
|
reset_ok = False
|
||||||
|
first.setdefault('pre_apl_spike_reset_mismatch', tick)
|
||||||
|
due = local[bounds[tick-18]:bounds[tick-17]] if tick >= 18 else np.empty(0, np.int64)
|
||||||
|
chunks = [np.arange(ptr[source], ptr[source+1], dtype=np.int64) for source in due]
|
||||||
|
indices = np.concatenate(chunks) if chunks else np.empty(0, np.int64)
|
||||||
|
expected_queue = _queue_digest(tick, graph['edge_id'][indices], (ref[graph['dst'][indices]] == 0).astype(np.uint8))
|
||||||
|
if expected_queue != run['queues'][tick]:
|
||||||
|
queue_ok = False
|
||||||
|
first.setdefault('queue_reconstruction_mismatch', tick)
|
||||||
|
_check(checks, role+'.request_refractory_gate', request_ok)
|
||||||
|
_check(checks, role+'.accepted_spikes_rejected_absent', delivered_ok)
|
||||||
|
_check(checks, role+'.all_ref_hashes_from_actual_events', ref_ok)
|
||||||
|
if run['pre']:
|
||||||
|
_check(checks, role+'.small_queue_independent_reconstruction', queue_ok)
|
||||||
|
_check(checks, role+'.spike_g_reset_before_apl', reset_ok)
|
||||||
|
if first:
|
||||||
|
differences[role+'.independent_accounting'] = first
|
||||||
|
|
||||||
|
|
||||||
|
def _check_apl_application(run, role, nodes, kc, checks, differences):
|
||||||
|
if not run['pre']:
|
||||||
|
return
|
||||||
|
common, local_kc, bundle_kc = np.intersect1d(nodes, kc, assume_unique=True, return_indices=True)
|
||||||
|
_compare_array(role+'.apl_keeps_voltage', run['pre']['v'], run['histories']['v'], checks, differences, 'float64')
|
||||||
|
_compare_array(role+'.apl_keeps_ref', run['pre']['ref'], run['histories']['ref'], checks, differences, 'int32')
|
||||||
|
expected = np.array(run['pre']['g'], copy=True)
|
||||||
|
delta = run['apl']['inhibition'][:, bundle_kc].astype(np.float64)*np.float64(.001)
|
||||||
|
expected[:, local_kc] = expected[:, local_kc]-delta
|
||||||
|
_compare_array(role+'.apl_unconditional_g_write', expected, run['histories']['g'], checks, differences, 'float64')
|
||||||
|
|
||||||
|
|
||||||
|
def _finish(report, checks, differences, used, out_json):
|
||||||
|
report['checks'] = {name: bool(value) for name, value in checks.items()}
|
||||||
|
report['differences'] = differences
|
||||||
|
report['pass_all'] = bool(checks) and all(checks.values()) and 'error' not in report
|
||||||
|
report['failed_checks'] = sorted(name for name, value in checks.items() if not value)
|
||||||
|
report['evidence_sha256'] = {str(path): file_hash(path) for path in sorted(used) if path.is_file()}
|
||||||
|
save(out_json, report)
|
||||||
|
return report
|
||||||
|
|
||||||
|
|
||||||
|
def compare(case_dir, gpu_dir, cpu_dir, out_json=None):
|
||||||
|
"""Strict independent closed-loop comparison; out_json=None is read-only."""
|
||||||
|
case_dir, gpu_dir, cpu_dir = Path(case_dir), Path(gpu_dir), Path(cpu_dir)
|
||||||
|
if out_json is not None:
|
||||||
|
require(not Path(out_json).exists(), 'Refusing existing comparison report')
|
||||||
|
checks, differences, used = {}, {}, set()
|
||||||
|
report = {'kind': 'shared-APL-component closed-loop byte-exact comparison', 'pass_all': False,
|
||||||
|
'case_dir': str(case_dir), 'gpu_dir': str(gpu_dir), 'cpu_dir': str(cpu_dir),
|
||||||
|
'tolerance': None, 'signed_zero_included': True, 'timing_fields_compared': False,
|
||||||
|
'independent_CPU_all_components_claim': False}
|
||||||
|
try:
|
||||||
|
spec = _read_json(case_dir/'spec.json', used)
|
||||||
|
steps, history = spec['steps'], spec['record_history']
|
||||||
|
require(type(steps) is int and steps > 0 and type(history) is bool and spec['dt_ms'] == .1,
|
||||||
|
'Invalid fixed case clock/history schema')
|
||||||
|
graph_dir, bundle_dir = Path(spec['graph_dir']), Path(spec['apl_bundle_dir'])
|
||||||
|
graph = {field: _read_array(graph_dir/(field+'.npy'), used) for field in
|
||||||
|
('nodes', 'edge_id', 'src', 'dst', 'ptr', 'signed_raw', 'weights')}
|
||||||
|
nodes = graph['nodes']
|
||||||
|
n, edges = len(nodes), len(graph['edge_id'])
|
||||||
|
require(n > 0 and edges > 0 and nodes.dtype == np.int32 and nodes.ndim == 1 and np.all((nodes >= 0) & (nodes < N_GLOBAL)) and
|
||||||
|
np.all(np.diff(nodes) > 0), 'Invalid canonical node identities')
|
||||||
|
require(graph['ptr'].dtype == np.int64 and graph['ptr'].shape == (n+1,) and graph['ptr'][0] == 0 and
|
||||||
|
graph['ptr'][-1] == edges and np.all(np.diff(graph['ptr']) >= 0), 'Invalid CSR')
|
||||||
|
for key, dtype in (('edge_id', 'int64'), ('src', 'int32'), ('dst', 'int32'), ('signed_raw', 'int64'), ('weights', 'float64')):
|
||||||
|
require(graph[key].dtype == np.dtype(dtype) and graph[key].shape == (edges,), 'Invalid graph '+key)
|
||||||
|
require(np.array_equal(graph['src'], np.repeat(np.arange(n, dtype=np.int32), np.diff(graph['ptr']))) and
|
||||||
|
np.all((graph['dst'] >= 0) & (graph['dst'] < n)), 'Invalid source/destination row mapping')
|
||||||
|
require(history == (n < 512) and (n < 512 or n == N_GLOBAL), 'Invalid small/full history declaration')
|
||||||
|
require(np.all(graph['edge_id'] >= 0) and np.all(np.diff(graph['edge_id']) > 0),
|
||||||
|
'Original canonical edge IDs must be unique and increasing')
|
||||||
|
if n == N_GLOBAL:
|
||||||
|
require(edges == 25582938 and np.array_equal(nodes, np.arange(n, dtype=np.int32)) and
|
||||||
|
np.array_equal(graph['edge_id'], np.arange(edges, dtype=np.int64)), 'Full canonical graph identity changed')
|
||||||
|
bundle = {name: _read_array(bundle_dir/name, used) for name in BUNDLE_FILES}
|
||||||
|
kc, apl_ids = bundle['kc_globals.npy'], bundle['apl_globals.npy']
|
||||||
|
require(kc.dtype == apl_ids.dtype == np.int32 and kc.shape == (4064,) and apl_ids.shape == (2,), 'Invalid APL/KC identities')
|
||||||
|
require(np.all((kc >= 0) & (kc < N_GLOBAL)) and np.all(np.diff(kc) > 0) and
|
||||||
|
np.all((apl_ids >= 0) & (apl_ids < N_GLOBAL)) and np.all(np.diff(apl_ids) > 0) and
|
||||||
|
not np.intersect1d(kc, apl_ids).size, 'APL/KC identities overlap or are invalid')
|
||||||
|
for key, shape in (('input_matrix.npy', (2, N_GLOBAL)), ('output_matrix.npy', (2, 4064))):
|
||||||
|
require(bundle[key].dtype == np.float32 and bundle[key].shape == shape and
|
||||||
|
np.isfinite(bundle[key]).all() and np.all(bundle[key] >= 0), 'Invalid normalized APL matrix')
|
||||||
|
gpu = _load_run(gpu_dir, 'gpu', n, edges, steps, history, spec['name'], used, checks)
|
||||||
|
cpu = _load_run(cpu_dir, 'cpu', n, edges, steps, history, spec['name'], used, checks)
|
||||||
|
_pair_outputs(gpu, cpu, checks, differences, n, steps, history)
|
||||||
|
used.add(case_dir/'requests.npz')
|
||||||
|
with np.load(case_dir/'requests.npz', allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == {'tick', 'neuron_idx'} and source['tick'].dtype == source['neuron_idx'].dtype == np.int32,
|
||||||
|
'Fixed request NPZ schema changed')
|
||||||
|
require(source['tick'].shape == source['neuron_idx'].shape and source['tick'].ndim == 1, 'Invalid sparse request shape')
|
||||||
|
requested = list(zip(map(int, source['tick']), map(int, source['neuron_idx'])))
|
||||||
|
for role, run in (('gpu', gpu), ('cpu', cpu)):
|
||||||
|
_independent_event_accounting(run, role, graph, requested, steps, checks, differences)
|
||||||
|
_check_apl_application(run, role, nodes, kc, checks, differences)
|
||||||
|
|
||||||
|
# Independently derive the effective clone. Original graph weights stay read-only.
|
||||||
|
cpu_weights = _read_array(cpu_dir/'weights.npy', used)
|
||||||
|
require(cpu_weights.dtype == np.float64 and cpu_weights.shape == (edges,), 'CPU effective weight schema mismatch')
|
||||||
|
expected_hash, base_hash, mask_hash = hashlib.sha256(), hashlib.sha256(), hashlib.sha256()
|
||||||
|
weight_ok, mask_count = True, 0
|
||||||
|
for start in range(0, edges, 1 << 20):
|
||||||
|
stop = min(edges, start+(1 << 20))
|
||||||
|
original = np.asarray(graph['weights'][start:stop])
|
||||||
|
require(np.isfinite(original).all(), 'Nonfinite original weights')
|
||||||
|
raw_expected = graph['signed_raw'][start:stop]*(.275*.001)
|
||||||
|
require(not np.any(_bit_mask(original, raw_expected)), 'Original SI weights differ from unaltered signed contacts')
|
||||||
|
mask = np.isin(nodes[graph['src'][start:stop]], apl_ids)
|
||||||
|
expected = original.copy()
|
||||||
|
expected[mask] = np.float64(0)
|
||||||
|
mask_count += int(mask.sum())
|
||||||
|
expected_hash.update(np.ascontiguousarray(expected, dtype='<f8').tobytes())
|
||||||
|
base_hash.update(np.ascontiguousarray(original, dtype='<f8').tobytes())
|
||||||
|
mask_hash.update(np.ascontiguousarray(graph['edge_id'][start:stop][mask], dtype='<i8').tobytes())
|
||||||
|
weight_ok &= not np.any(_bit_mask(expected, cpu_weights[start:stop]))
|
||||||
|
expected_sha = expected_hash.hexdigest()
|
||||||
|
_check(checks, 'cpu.effective_weights_independent_bytes', weight_ok)
|
||||||
|
for role, run in (('gpu', gpu), ('cpu', cpu)):
|
||||||
|
_check(checks, role+'.effective_weights_raw_sha', run['summary'].get('effective_weights_raw_sha256') == expected_sha)
|
||||||
|
_check(checks, role+'.apl_fast_edge_count', run['summary'].get('apl_fast_edges_zeroed') == mask_count)
|
||||||
|
_check(checks, role+'.kc_target_count', run['summary'].get('kc_targets_present') == len(np.intersect1d(nodes, kc)))
|
||||||
|
mask_audit = _read_json(cpu_dir/'apl-mask-audit.json', used)
|
||||||
|
_check(checks, 'cpu.mask_provenance', mask_audit['count'] == mask_count and
|
||||||
|
mask_audit['ordered_original_edge_id_sha256'] == mask_hash.hexdigest() and
|
||||||
|
mask_audit['base_weight_raw_bytes_sha256'] == base_hash.hexdigest() and
|
||||||
|
mask_audit['effective_weights_raw_sha256'] == expected_sha and mask_audit['base_graph_files_modified'] is False)
|
||||||
|
|
||||||
|
case_hashes = {name: file_hash(case_dir/name) for name in ('spec.json', 'requests.npz')}
|
||||||
|
if (case_dir/'arrays.npz').exists():
|
||||||
|
case_hashes['arrays.npz'] = file_hash(case_dir/'arrays.npz')
|
||||||
|
used.add(case_dir/'arrays.npz')
|
||||||
|
baseline_coeff = _read_json(Path(spec['coefficients_path']), used)
|
||||||
|
actual_coeff = _read_json(cpu_dir/'coefficients.json', used)
|
||||||
|
_check(checks, 'cpu.actual_author_coefficients_exact', all(float(actual_coeff[key]).hex() == float(baseline_coeff[key]).hex()
|
||||||
|
for key in COEFFICIENTS))
|
||||||
|
audit = _read_json(cpu_dir/'input-audit.json', used)
|
||||||
|
expected_graph_hashes = {name: file_hash(graph_dir/name) for name in
|
||||||
|
tuple(field+'.npy' for field in graph)+('completeness.csv', 'connectivity.parquet')}
|
||||||
|
bundle_hashes = {name: file_hash(bundle_dir/name) for name in BUNDLE_FILES}
|
||||||
|
_check(checks, 'cpu.read_actual_case', audit['spec'] == spec and audit['case_hashes'] == case_hashes)
|
||||||
|
_check(checks, 'cpu.graph_hashes', audit['graph_hashes'] == expected_graph_hashes)
|
||||||
|
_check(checks, 'cpu.bundle_hashes', audit['bundle_hashes'] == bundle_hashes)
|
||||||
|
_check(checks, 'cpu.no_candidate_trace_input', audit.get('candidate_trace_used_as_input') is False and
|
||||||
|
cpu['summary'].get('candidate_trace_used_as_input') is False)
|
||||||
|
_check(checks, 'cpu.worker_source_hash', audit['legacy_apl_worker_sha256'] == file_hash(spec['legacy_apl_worker']))
|
||||||
|
_check(checks, 'cpu.coefficient_input_hash', audit['coefficients_sha256'] == file_hash(spec['coefficients_path']))
|
||||||
|
gpu_hashes = dict(case_hashes, **{'base_weights.npy': file_hash(graph_dir/'weights.npy'),
|
||||||
|
'coefficients.json': file_hash(spec['coefficients_path'])})
|
||||||
|
_check(checks, 'gpu.input_hashes', gpu['summary']['input_sha256'] == gpu_hashes)
|
||||||
|
for role, run in (('gpu', gpu), ('cpu', cpu)):
|
||||||
|
component = run['component']
|
||||||
|
_check(checks, role+'.actual_component_bundle_bytes', component['files_sha256'] == bundle_hashes and
|
||||||
|
component['array_sha256'] == {name: raw_hash(value) for name, value in bundle.items()})
|
||||||
|
_check(checks, role+'.component_dimensions_clock', component.get('ok') is True and
|
||||||
|
component['protocol'] == 'phase4ag-apl-v1' and component['n_neurons'] == N_GLOBAL and
|
||||||
|
component['n_apl'] == 2 and component['n_kc'] == 4064 and component['dt_ms'] == .1)
|
||||||
|
decay = np.float32(math.exp(-.1/20.0))
|
||||||
|
gain = np.float32(.01)
|
||||||
|
_check(checks, role+'.frozen_apl_constants', component['decay_f32_bits'] == f'{int(decay.view(np.uint32)):08x}' and
|
||||||
|
component['gain_f32_bits'] == f'{int(gain.view(np.uint32)):08x}')
|
||||||
|
env = component['environment']
|
||||||
|
_check(checks, role+'.component_precision_environment', env['cuda_matmul_allow_tf32'] is False and
|
||||||
|
env['float32_matmul_precision'] == 'highest' and env['precision_configuration_changed_by_component'] is False and
|
||||||
|
'4090' in env['device_name'])
|
||||||
|
environment = _read_json(cpu_dir/'environment.json', used)
|
||||||
|
_check(checks, 'cpu.pinned_environment', environment['packages']['brian2'] == '2.5.1' and
|
||||||
|
environment['packages']['numpy'] == '1.22.3' and environment['packages']['sympy'] == '1.12' and
|
||||||
|
environment['Torch_imported_into_Brian'] is False and environment['author_precision'] == 'float64')
|
||||||
|
queue_audit = _read_json(cpu_dir/'queue-audit.json', used)
|
||||||
|
_check(checks, 'cpu.queue_observer_coverage', queue_audit['peek_calls'] == queue_audit['advance_calls'] == steps and
|
||||||
|
queue_audit['same_peek_object_returned'] is True and queue_audit['zero_weight_and_refractory_rejected_edges_retained'] is True)
|
||||||
|
_check(checks, 'cpu.sidecar_complete', cpu['summary']['APL_worker_exit_status'] == 0 and cpu['summary']['APL_worker_ticks'] == steps)
|
||||||
|
report.update(case=spec['name'], steps=steps, nodes=n, edges=edges, record_history=history,
|
||||||
|
total_spikes=len(gpu['state']['step']), active_neurons=int(np.count_nonzero(gpu['state']['counts'])),
|
||||||
|
requested=len(requested), accepted_requests=sum(row['accepted'] for row in gpu['requests']),
|
||||||
|
rejected_requests=sum(row['rejected'] for row in gpu['requests']),
|
||||||
|
arriving_edges=sum(row['count'] for row in gpu['queues']),
|
||||||
|
accepted_arriving_edges=sum(row['accepted_count'] for row in gpu['queues']),
|
||||||
|
apl_fast_edges_zeroed=mask_count, effective_weights_raw_sha256=expected_sha,
|
||||||
|
component_environment=gpu['component']['environment'],
|
||||||
|
limits=['APL Torch primitives are shared; original AST component validation is a separate required gate.',
|
||||||
|
'Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.',
|
||||||
|
'For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.',
|
||||||
|
'This is exact agreement for the declared trajectory, not physiological validity or learning.'])
|
||||||
|
except Exception as error:
|
||||||
|
report['error'] = {'type': type(error).__name__, 'message': str(error)}
|
||||||
|
return _finish(report, checks, differences, used, out_json)
|
||||||
|
|
||||||
|
|
||||||
|
def compare_gpu_repeats(first, second, out_json=None):
|
||||||
|
"""Repeat equality only; the first run's independent oracle gate is separate."""
|
||||||
|
first, second = Path(first), Path(second)
|
||||||
|
if out_json is not None:
|
||||||
|
require(not Path(out_json).exists(), 'Refusing existing repeat report')
|
||||||
|
checks, differences, used = {}, {}, set()
|
||||||
|
report = {'kind': 'fresh-GPU-run exact repeat comparison', 'first': str(first), 'second': str(second),
|
||||||
|
'pass_all': False, 'tolerance': None, 'signed_zero_included': True, 'timing_fields_compared': False,
|
||||||
|
'scope': 'Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()'}
|
||||||
|
try:
|
||||||
|
summary = _read_json(first/'summary.json', used)
|
||||||
|
n, edges, steps, name, history = (summary[key] for key in ('nodes', 'edges', 'steps', 'case', 'record_history'))
|
||||||
|
require(type(n) is int and type(edges) is int and type(steps) is int and n > 0 and edges > 0 and steps > 0 and
|
||||||
|
type(history) is bool and history == (n < 512), 'Invalid repeat dimensions')
|
||||||
|
left = _load_run(first, 'first_gpu', n, edges, steps, history, name, used, checks)
|
||||||
|
right = _load_run(second, 'second_gpu', n, edges, steps, history, name, used, checks)
|
||||||
|
_pair_outputs(left, right, checks, differences, n, steps, history)
|
||||||
|
stable = ('case', 'complete', 'pass_all', 'steps', 'completed_ticks', 'nodes', 'edges', 'precision',
|
||||||
|
'apl_precision', 'state_units', 'total_spikes', 'requested', 'accepted_requests', 'rejected_requests',
|
||||||
|
'arriving_edges', 'accepted_arriving_edges', 'counts_match_sparse_events', 'all_finite', 'record_history',
|
||||||
|
'apl_fast_edges_zeroed', 'kc_targets_present', 'effective_weights_raw_sha256', 'apl_schedule',
|
||||||
|
'apl_si_conversion', 'build', 'sealed_ae_backend_sha256', 'learning', 'input_sha256')
|
||||||
|
for key in stable:
|
||||||
|
_check(checks, 'summary.'+key, key in left['summary'] and key in right['summary'] and
|
||||||
|
left['summary'][key] == right['summary'][key])
|
||||||
|
if not checks['summary.'+key]:
|
||||||
|
differences['summary.'+key] = {'first': left['summary'].get(key), 'second': right['summary'].get(key)}
|
||||||
|
report.update(case=name, steps=steps, nodes=n, edges=edges, record_history=history,
|
||||||
|
total_spikes=len(left['state']['step']),
|
||||||
|
explicit_exclusions=['wall_seconds', 'diagnostic_simulation_seconds', 'build_or_cache_seconds',
|
||||||
|
'peak_allocated_vram_bytes', 'peak_reserved_vram_bytes'])
|
||||||
|
except Exception as error:
|
||||||
|
report['error'] = {'type': type(error).__name__, 'message': str(error)}
|
||||||
|
return _finish(report, checks, differences, used, out_json)
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"phase": "4AG",
|
||||||
|
"name": "author-apl-lab-v1",
|
||||||
|
"human_authorization": "允许独立新模型分支测试动力学假设",
|
||||||
|
"gpu_uuid": "GPU-79f3a85d-adce-7833-7003-6488140ca596",
|
||||||
|
"neurons": 166700,
|
||||||
|
"edges": 25582938,
|
||||||
|
"raw_weight_sum": 124177617,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"apl": {"tau_ms": 20.0, "gain": 0.01, "normalization": 1.0},
|
||||||
|
"hypothesis": "Author LIF plus unchanged legacy graded APL operator at end, after reset, unconditional KC g write. Mixed precision: h32 promoted to float64, then multiplied by float64 .001 SI, then subtracted. Not original author's APL model.",
|
||||||
|
"fixtures": ["zero", "pn_pulse", "kc_ref_boundary", "two_sources", "arrival_collision", "natural_request", "apl_only", "high_fanin"],
|
||||||
|
"fixture_repeats": 3,
|
||||||
|
"calibration": {"split": "calibration", "odor_count": 6, "modes": ["physiological", "matched_energy"], "seeds": [51101,51102,51103,51104,51105], "duration_ms": 100.0, "median_scope": "original frozen 12-odor panel", "full_oracle_probes": ["cal-physiological-00-s51101", "cal-matched_energy-00-s51101"], "repeat_first_seed_each_odor": true},
|
||||||
|
"gates": {"sparse_min_fraction": 0.03, "sparse_max_fraction": 0.09, "max_fraction_strict": 0.5, "min_fraction_strict": 0.0, "minimum_separable_odor_pairs": 3, "same_jaccard_gt_between": true, "between_euclidean_gt_within": true, "both_modes_required": true, "finite_required": true, "repeat_exact_required": true},
|
||||||
|
"training": false,
|
||||||
|
"heldout_dynamic_access": false,
|
||||||
|
"candidate_generation": false,
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"scope": "Semantic compatibility and fixed old CAL only. Shared-APL-component closed-loop Brian oracle plus independent arithmetic audit; never claim all-component independent CPU equivalence or learning success. No parameter/input/site/window selection from results."
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import hashlib
|
||||||
|
import importlib.util
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT=Path('/data/digital-drosophila')
|
||||||
|
MODEL=Path(__file__).resolve().parent
|
||||||
|
EXP=ROOT/'experiments/phase4ag-author-apl'
|
||||||
|
AF_MODEL=ROOT/'models/male-cns-lif/author-fullgraph-lab-v1'
|
||||||
|
AF_EXP=ROOT/'experiments/phase4af-author-fullgraph'
|
||||||
|
AD_EXP=ROOT/'experiments/phase4ad-author-semantics'
|
||||||
|
CFG=json.loads((MODEL/'config.json').read_text(encoding='utf-8'))
|
||||||
|
|
||||||
|
def digest(path):
|
||||||
|
h=hashlib.sha256()
|
||||||
|
with Path(path).open('rb') as f:
|
||||||
|
for b in iter(lambda:f.read(8<<20),b''):h.update(b)
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
def save(path,value):
|
||||||
|
path=Path(path);path.parent.mkdir(parents=True,exist_ok=True)
|
||||||
|
with path.open('x',encoding='utf-8') as f:json.dump(value,f,indent=2,ensure_ascii=False,allow_nan=False);f.write('\n')
|
||||||
|
|
||||||
|
def sources():
|
||||||
|
return {p.name:digest(p) for p in sorted(MODEL.iterdir()) if p.is_file() and p.name not in ('manifest.json','checksums.sha256')}
|
||||||
|
|
||||||
|
def integrity():
|
||||||
|
spec=importlib.util.spec_from_file_location('frozen_af_context',AF_MODEL/'context.py')
|
||||||
|
mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod)
|
||||||
|
result=mod.integrity()
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0,str(ROOT/'models/male-cns-lif/terminal-scope-diagnostic-v1'))
|
||||||
|
from diagnostic import manifest_check
|
||||||
|
for p in (AF_MODEL,AF_EXP):result[str(p.relative_to(ROOT))]=manifest_check(p,digest)
|
||||||
|
assert all(r['pass'] for r in result.values())
|
||||||
|
return result
|
||||||
|
|
||||||
|
def check():
|
||||||
|
p=json.loads((EXP/'protocol/preregistered.json').read_text())
|
||||||
|
assert p['sources']==sources(),'Source changed after preregistration'
|
||||||
|
for row in p['inputs']:assert digest(ROOT/row['path'])==row['sha256'],row['path']
|
||||||
|
for row in json.loads((EXP/'protocol/prepared-hashes.json').read_text()):
|
||||||
|
assert digest(EXP/row['path'])==row['sha256'],row['path']
|
||||||
|
return p
|
||||||
|
|
||||||
|
def budget():
|
||||||
|
size=sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file())
|
||||||
|
assert size<CFG['output_budget_bytes'],'New output resource budget exceeded'
|
||||||
|
return size
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
"""Seal a completed gate or preserved failure; never claim learning."""
|
||||||
|
import json
|
||||||
|
from context import ROOT,MODEL,EXP,CFG,check,save,digest,integrity,budget
|
||||||
|
|
||||||
|
|
||||||
|
def seal(root):
|
||||||
|
assert not (root/'manifest.json').exists() and not (root/'checksums.sha256').exists()
|
||||||
|
rows=[dict(path=str(p.relative_to(root)),bytes=p.stat().st_size,sha256=digest(p))
|
||||||
|
for p in sorted(root.rglob('*')) if p.is_file() and '__pycache__' not in p.parts]
|
||||||
|
save(root/'manifest.json',dict(root=str(root),files=rows))
|
||||||
|
with (root/'checksums.sha256').open('x') as f:
|
||||||
|
for row in rows:f.write(row['sha256']+' '+row['path']+'\n')
|
||||||
|
f.write(digest(root/'manifest.json')+' manifest.json\n')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
from compare import compare,compare_gpu_repeats
|
||||||
|
check();budget();comparisons=[];repeats={};components={}
|
||||||
|
for p in sorted((EXP/'audit').glob('compare-*.json')):
|
||||||
|
name=p.stem[len('compare-'):]
|
||||||
|
actual=compare(EXP/'cases'/name,EXP/'gpu'/(name+'-r0'),EXP/'oracle'/name,None)
|
||||||
|
assert actual==json.loads(p.read_text()),'Changed raw closed-loop evidence: '+name
|
||||||
|
comparisons.append(dict(case=name,pass_all=actual['pass_all']))
|
||||||
|
for p in sorted((EXP/'audit').glob('repeat-*.json')):
|
||||||
|
name,repeat=p.stem[len('repeat-'):].rsplit('-r',1)
|
||||||
|
actual=compare_gpu_repeats(EXP/'gpu'/(name+'-r0'),EXP/'gpu'/f'{name}-r{repeat}',None)
|
||||||
|
assert actual==json.loads(p.read_text()),'Changed raw repeat evidence: '+name
|
||||||
|
repeats[f'{name}-r{repeat}']=actual['pass_all']
|
||||||
|
for p in (EXP/'component-audit').glob('*.json'):
|
||||||
|
result=json.loads(p.read_text())
|
||||||
|
components[p.stem]=result['pass_all']
|
||||||
|
for filename,sha in result.get('input_sha256',{}).items():
|
||||||
|
assert digest(EXP/'gpu'/(p.stem+'-r0')/filename)==sha
|
||||||
|
gates={}
|
||||||
|
for name in ('fixtures','probes','calibration'):
|
||||||
|
path=EXP/'audit'/(name+'-gate.json')
|
||||||
|
gates[name]=json.loads(path.read_text()) if path.exists() else None
|
||||||
|
calpath=EXP/'calibration/summary.json'
|
||||||
|
cal=json.loads(calpath.read_text()) if calpath.exists() else None
|
||||||
|
if cal is not None:
|
||||||
|
from calibration import summarize
|
||||||
|
assert summarize(out_json=None)==cal,'CAL raw evidence changed'
|
||||||
|
frozen=json.loads((EXP/'regression/frozen-five.json').read_text())
|
||||||
|
after=integrity();save(EXP/'regression/old-integrity-after.json',after)
|
||||||
|
stops=[dict(path=str(p.relative_to(EXP)),report=json.loads(p.read_text())) for p in sorted((EXP/'audit').glob('stopped-*.json'))]
|
||||||
|
expected_cases=CFG['fixtures']+CFG['calibration']['full_oracle_probes']
|
||||||
|
expected_repeats=[f'{name}-r{r}' for name in CFG['fixtures'] for r in range(1,CFG['fixture_repeats'])]
|
||||||
|
compared={x['case']:x['pass_all'] for x in comparisons}
|
||||||
|
missing=dict(comparisons=sorted(set(expected_cases)-set(compared)),
|
||||||
|
components=sorted(set(expected_cases)-set(components)),repeats=sorted(set(expected_repeats)-set(repeats)))
|
||||||
|
evidence_ok=(set(compared)==set(components)==set(expected_cases) and set(repeats)==set(expected_repeats) and
|
||||||
|
all(compared.values()) and all(components.values()) and all(repeats.values()))
|
||||||
|
numerical=evidence_ok and all(gates[x] is not None and gates[x]['pass_all'] for x in ('fixtures','probes'))
|
||||||
|
representation=bool(cal is not None and cal['pass_all'])
|
||||||
|
if numerical:status='PASS-FIXED-CAL-REPRESENTATION' if representation else 'FAIL-FIXED-CAL-REPRESENTATION' if cal is not None else 'INCOMPLETE-CAL-EXECUTION'
|
||||||
|
else:status='FAIL-NUMERICAL-OR-AUDIT-GATE' if any(not p for group in (compared,components,repeats) for p in group.values()) else 'INCOMPLETE-NUMERICAL-EXECUTION'
|
||||||
|
oldpass=bool(frozen['pass_all'] and all(r['pass'] for r in after.values()))
|
||||||
|
if not oldpass:status='FAIL-FROZEN-INTEGRITY-OR-REGRESSION'
|
||||||
|
measurements=[]
|
||||||
|
for p in sorted((EXP/'gpu').glob('*/summary.json')):
|
||||||
|
s=json.loads(p.read_text())
|
||||||
|
measurements.append({k:s[k] for k in ('case','total_spikes','accepted_requests','nodes','edges','diagnostic_simulation_seconds','peak_allocated_vram_bytes')})
|
||||||
|
result=dict(status=status,numerical_gate_pass=bool(numerical),fixed_CAL_representation_pass=representation,
|
||||||
|
gates=gates,closed_loop_comparisons=comparisons,component_results=components,repeat_results=repeats,
|
||||||
|
missing_numerical_evidence=missing,calibration=cal,stopped=stops,
|
||||||
|
old_frozen_integrity_and_five_reference_pass=oldpass,measurements=measurements,
|
||||||
|
unchanged_APL_parameters=CFG['apl'],author_LIF_precision='float64',legacy_APL_precision='float32',
|
||||||
|
explicit_hypothesis=CFG['hypothesis'],APL_nonKC_fast_edges_unreplaced=1212,
|
||||||
|
shared_APL_component_oracle_limitation=True,whole_brain_universal_equivalence_claim=False,
|
||||||
|
heldout_generalization_tested=False,formal_AB_tested=False,learning_achieved=False,candidate_generated=False,
|
||||||
|
payload_bytes_before_manifest=budget(),
|
||||||
|
next_gate='Independent seeds/novel-odor representation, then credit specificity; no learning promotion from CAL' if numerical and representation else
|
||||||
|
'Audit first failure in this explicitly declared hypothesis; no gain search, no heldout tuning, no conditioning')
|
||||||
|
save(EXP/'audit/final-status.json',result)
|
||||||
|
lines=['# Phase 4AG: author LIF + unchanged legacy graded APL','',f'Status: `{status}`.','',
|
||||||
|
f'Numerical closed-loop gate: {numerical}; original complete fixed six-CAL gate: {representation}.',
|
||||||
|
'The independent Brian LIF and candidate use independent state but share the APL arithmetic component. Original frozen APL AST replay and a float64 error audit are separately recorded.',
|
||||||
|
'Author LIF uses float64; APL retains float32, tau20ms/gain0.01/normalization1, full original matrices and order. No learning/parameter search.',
|
||||||
|
'The explicitly hypothesized unconditional end-APL write includes refractory KC. Original fast APL mask leaves1,212 non-KC edges unreplaced; this scope limitation was not silently fixed.',
|
||||||
|
f'Old checksums and five frozen reference trials: {oldpass}.',
|
||||||
|
f'Successfully compared cases: {comparisons}.',
|
||||||
|
'Detailed CAL, exact comparisons, component errors, event/request traces and execution exceptions are linked from audit/final-status.json.',
|
||||||
|
'Wall/VRAM here include per-tick CPU synchronization, IPC and hashes. They are diagnostic costs, not runtime-performance benchmarks.',
|
||||||
|
'No heldout dynamic outputs, formal A/B, learning, game, reward, decoder or new candidate.',
|
||||||
|
'Next gate: '+result['next_gate'],'']
|
||||||
|
with (EXP/'REPORT.md').open('x',encoding='utf-8') as f:f.write('\n'.join(lines))
|
||||||
|
check();seal(MODEL);seal(EXP);print(status,flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
"""Diagnostic author-float64 LIF plus frozen legacy-float32 APL overlay.
|
||||||
|
|
||||||
|
The sealed Phase 4AE CUDA operators are reused without modification. APL is
|
||||||
|
an explicitly mixed-precision engineering overlay, not an author-model claim.
|
||||||
|
All CUDA/CPU synchronization here is diagnostic; no performance claim is made.
|
||||||
|
"""
|
||||||
|
from functools import lru_cache
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
import types
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import torch
|
||||||
|
|
||||||
|
from legacy_apl_worker import LegacyAPL, N_NEURONS, file_sha256, array_sha256
|
||||||
|
|
||||||
|
|
||||||
|
SOURCE_ROOT = Path(__file__).resolve().parent
|
||||||
|
AE_MODEL = SOURCE_ROOT.parent / "author-runtime-lab-v1"
|
||||||
|
AF_MODEL = SOURCE_ROOT.parent / "author-fullgraph-lab-v1"
|
||||||
|
COEFFICIENT_NAMES = ("gd", "c0", "cg", "cv", "threshold", "reset", "seed_volt")
|
||||||
|
REQUEST_FIELDS = ("tick", "neuron_idx", "attempted", "accepted", "rejected")
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def write_json(path, value):
|
||||||
|
with Path(path).open("x", encoding="utf-8") as output:
|
||||||
|
json.dump(value, output, indent=2, allow_nan=False)
|
||||||
|
output.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def raw_hash(value, dtype):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value, dtype=dtype).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def load_source(path, name):
|
||||||
|
module = types.ModuleType(name)
|
||||||
|
module.__file__ = str(path)
|
||||||
|
exec(compile(Path(path).read_bytes(), str(path), "exec"), module.__dict__)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def sealed_backend():
|
||||||
|
return load_source(AE_MODEL / "gpu_backend.py", "phase4ag_sealed_ae_backend")
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def queue_function():
|
||||||
|
return load_source(AF_MODEL / "oracle_full.py", "phase4ag_sealed_af_queue").queue_summary
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=4)
|
||||||
|
def load_graph(graph_directory):
|
||||||
|
root = Path(graph_directory)
|
||||||
|
require(root.is_absolute(), "graph_dir must be absolute")
|
||||||
|
graph = {}
|
||||||
|
for name, dtype in (("nodes", np.int32), ("edge_id", np.int64), ("src", np.int32),
|
||||||
|
("dst", np.int32), ("signed_raw", np.int64), ("ptr", np.int64),
|
||||||
|
("weights", np.float64)):
|
||||||
|
value = np.load(root / (name + ".npy"), mmap_mode="r", allow_pickle=False)
|
||||||
|
require(value.dtype == dtype and value.ndim == 1, "Graph dtype/rank mismatch: " + name)
|
||||||
|
graph[name] = value
|
||||||
|
nodes, edges = graph["nodes"], graph["edge_id"]
|
||||||
|
n, e = len(nodes), len(edges)
|
||||||
|
require(0 < n <= N_NEURONS and bool(np.all((nodes >= 0) & (nodes < N_NEURONS))) and
|
||||||
|
bool(np.all(np.diff(nodes) > 0)), "Global node IDs must be sorted unique")
|
||||||
|
require(n < 512 or (n == N_NEURONS and np.array_equal(nodes, np.arange(N_NEURONS, dtype=np.int32))),
|
||||||
|
"Only small fixtures or the intact frozen full graph are permitted")
|
||||||
|
require(n != N_NEURONS or e == 25582938, "Full graph edge count changed")
|
||||||
|
for name in ("src", "dst", "signed_raw", "weights"):
|
||||||
|
require(graph[name].shape == (e,), "Graph edge array length mismatch: " + name)
|
||||||
|
ptr = graph["ptr"]
|
||||||
|
require(ptr.shape == (n + 1,) and ptr[0] == 0 and ptr[-1] == e and
|
||||||
|
bool(np.all(np.diff(ptr) >= 0)), "Invalid graph CSR")
|
||||||
|
require(np.array_equal(graph["src"], np.repeat(np.arange(n, dtype=np.int32), np.diff(ptr))),
|
||||||
|
"Source order does not match CSR")
|
||||||
|
# Global edge IDs need not equal local row indices in a fixture.
|
||||||
|
for start in range(0, e, 1 << 20):
|
||||||
|
stop = min(start + (1 << 20), e)
|
||||||
|
require(bool(np.all((graph["dst"][start:stop] >= 0) & (graph["dst"][start:stop] < n))),
|
||||||
|
"Local destination out of range")
|
||||||
|
require(bool(np.isfinite(graph["weights"][start:stop]).all()), "Nonfinite base SI weights")
|
||||||
|
require(np.array_equal(np.sign(graph["weights"][start:stop]), np.sign(graph["signed_raw"][start:stop])),
|
||||||
|
"Base weight sign/zero pattern differs from frozen raw contacts")
|
||||||
|
lo = max(0, start - 1)
|
||||||
|
require(bool(np.all(edges[start:stop] >= 0)) and bool(np.all(np.diff(edges[lo:stop]) > 0)),
|
||||||
|
"Global edge IDs must retain canonical increasing source/edge order")
|
||||||
|
return graph
|
||||||
|
|
||||||
|
|
||||||
|
def load_inputs(case_dir):
|
||||||
|
spec = json.loads((case_dir / "spec.json").read_text(encoding="utf-8"))
|
||||||
|
for name in ("name", "steps", "dt_ms", "duration_ms", "model", "graph_dir", "apl",
|
||||||
|
"apl_bundle_dir", "coefficients_path", "record_history"):
|
||||||
|
require(name in spec, "Missing case field: " + name)
|
||||||
|
steps = spec["steps"]
|
||||||
|
require(type(steps) is int and 0 < steps <= 1000 and float(spec["dt_ms"]) == .1 and
|
||||||
|
float(spec["duration_ms"]) == steps * .1, "Unexpected steps/dt/duration")
|
||||||
|
require(type(spec["record_history"]) is bool, "record_history must be Boolean")
|
||||||
|
require(spec["apl"] == {"tau_ms": 20, "gain": .01, "normalization": 1}, "Frozen APL parameters changed")
|
||||||
|
for name in ("graph_dir", "apl_bundle_dir", "coefficients_path"):
|
||||||
|
require(Path(spec[name]).is_absolute(), "Input path must be absolute: " + name)
|
||||||
|
model = spec["model"]
|
||||||
|
for name in ("resting_potential_mv", "threshold_mv", "reset_potential_mv", "synaptic_delay_ms",
|
||||||
|
"refractory_ms", "w_syn_mv_per_anatomical_synapse"):
|
||||||
|
require(name in model and math.isfinite(float(model[name])), "Invalid model field: " + name)
|
||||||
|
require(float(model["synaptic_delay_ms"]) == 1.8 and float(model["refractory_ms"]) == 2.2 and
|
||||||
|
float(model["w_syn_mv_per_anatomical_synapse"]) == .275, "Frozen delay/ref/W_syn changed")
|
||||||
|
coeff = json.loads(Path(spec["coefficients_path"]).read_text(encoding="utf-8"))
|
||||||
|
for name in COEFFICIENT_NAMES:
|
||||||
|
require(name in coeff and math.isfinite(float(coeff[name])), "Invalid author coefficient: " + name)
|
||||||
|
require(coeff["threshold"] == float(model["threshold_mv"]) * .001 and
|
||||||
|
coeff["reset"] == float(model["reset_potential_mv"]) * .001, "Coefficient threshold/reset mismatch")
|
||||||
|
graph = load_graph(str(Path(spec["graph_dir"]).resolve()))
|
||||||
|
n = len(graph["nodes"])
|
||||||
|
require(spec["record_history"] == (n < 512), "Fixtures need dense history; full graph must not duplicate dense histories")
|
||||||
|
with np.load(case_dir / "requests.npz", allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == {"tick", "neuron_idx"}, "Request sparse schema changed")
|
||||||
|
ticks, requested = source["tick"].copy(), source["neuron_idx"].copy()
|
||||||
|
require(ticks.dtype == np.int32 and requested.dtype == np.int32 and ticks.ndim == 1 and
|
||||||
|
ticks.shape == requested.shape, "Invalid sparse request dtype/shape")
|
||||||
|
require(bool(np.all((ticks >= 0) & (ticks < steps))), "Request tick outside trial")
|
||||||
|
if len(ticks) > 1:
|
||||||
|
require(bool(np.all((ticks[1:] > ticks[:-1]) |
|
||||||
|
((ticks[1:] == ticks[:-1]) & (requested[1:] > requested[:-1])))),
|
||||||
|
"Requests must be sorted unique by tick/global neuron")
|
||||||
|
local = np.searchsorted(graph["nodes"], requested)
|
||||||
|
require(bool(np.all(local < n)) and np.array_equal(graph["nodes"][local], requested),
|
||||||
|
"Requested neuron absent from graph")
|
||||||
|
initial = {"initial_v_mv": np.full(n, float(model["resting_potential_mv"]), dtype=np.float64),
|
||||||
|
"initial_g_mv": np.zeros(n, dtype=np.float64)}
|
||||||
|
initial_path = case_dir / "arrays.npz"
|
||||||
|
if initial_path.exists():
|
||||||
|
with np.load(initial_path, allow_pickle=False) as source:
|
||||||
|
require(set(source.files).issubset(initial), "Unexpected initial-state array")
|
||||||
|
for name in source.files:
|
||||||
|
value = source[name]
|
||||||
|
require(value.dtype == np.float64 and value.shape == (n,) and bool(np.isfinite(value).all()),
|
||||||
|
"Invalid initial state: " + name)
|
||||||
|
initial[name] = value.copy()
|
||||||
|
return spec, graph, coeff, ticks, requested, local, initial
|
||||||
|
|
||||||
|
|
||||||
|
def new_array(path, dtype, shape):
|
||||||
|
require(not Path(path).exists(), "Refusing existing output: " + str(path))
|
||||||
|
return np.lib.format.open_memmap(path, mode="w+", dtype=dtype, shape=shape)
|
||||||
|
|
||||||
|
|
||||||
|
def run_gpu(case_dir, out_dir, build_root):
|
||||||
|
"""Run fresh candidate state; never consume oracle/candidate APL traces.
|
||||||
|
|
||||||
|
pass_all denotes internal recording/finite integrity only. Independent
|
||||||
|
comparison and the original complete representation gate are separate.
|
||||||
|
"""
|
||||||
|
case_dir, out_dir = Path(case_dir), Path(out_dir)
|
||||||
|
require(not out_dir.exists(), "Refusing existing output directory: " + str(out_dir))
|
||||||
|
out_dir.mkdir(parents=True, exist_ok=False)
|
||||||
|
start, tick, completed = time.perf_counter(), -1, 0
|
||||||
|
maps = {}
|
||||||
|
try:
|
||||||
|
spec, graph, coeff, request_ticks, request_nodes, request_local, initial = load_inputs(case_dir)
|
||||||
|
require(torch.cuda.is_available() and torch.cuda.device_count() == 1 and
|
||||||
|
"4090" in torch.cuda.get_device_name(), "Only the declared single visible RTX4090 is permitted")
|
||||||
|
ext, build = sealed_backend().build_extension(build_root)
|
||||||
|
build_done = time.perf_counter()
|
||||||
|
apl = LegacyAPL(spec["apl_bundle_dir"], spec["dt_ms"])
|
||||||
|
write_json(out_dir / "apl-component.json", apl.metadata)
|
||||||
|
device = apl.device
|
||||||
|
torch.cuda.reset_peak_memory_stats(device)
|
||||||
|
n, e, steps = len(graph["nodes"]), len(graph["edge_id"]), spec["steps"]
|
||||||
|
|
||||||
|
def upload(value, dtype):
|
||||||
|
return torch.from_numpy(np.array(value, copy=True, order="C")).to(device=device, dtype=dtype).contiguous()
|
||||||
|
|
||||||
|
indptr, dst = upload(graph["ptr"], torch.int64), upload(graph["dst"], torch.int32)
|
||||||
|
global_nodes_gpu = upload(graph["nodes"], torch.int64)
|
||||||
|
base_weights = upload(graph["weights"], torch.float64)
|
||||||
|
weights = base_weights.clone()
|
||||||
|
del base_weights
|
||||||
|
local_apl = np.flatnonzero(np.isin(graph["nodes"], apl.apl_globals)).astype(np.int64)
|
||||||
|
apl_out_mask = np.isin(graph["src"], local_apl)
|
||||||
|
if bool(np.any(apl_out_mask)):
|
||||||
|
weights[upload(apl_out_mask, torch.bool)] = 0.0
|
||||||
|
effective_hash = hashlib.sha256()
|
||||||
|
for offset in range(0, e, 1 << 20):
|
||||||
|
effective_hash.update(weights[offset:offset + (1 << 20)].cpu().numpy().astype("<f8", copy=False).tobytes())
|
||||||
|
common_kc, local_kc, full_kc = np.intersect1d(graph["nodes"], apl.kc_globals, assume_unique=True, return_indices=True)
|
||||||
|
kc_local_gpu, kc_full_gpu = upload(local_kc, torch.int64), upload(full_kc, torch.int64)
|
||||||
|
v = upload(initial["initial_v_mv"] * .001, torch.float64)
|
||||||
|
g = upload(initial["initial_g_mv"] * .001, torch.float64)
|
||||||
|
ref = torch.zeros(n, device=device, dtype=torch.int32)
|
||||||
|
counts = torch.zeros(n, device=device, dtype=torch.int32)
|
||||||
|
requests = torch.zeros(n, device=device, dtype=torch.uint8)
|
||||||
|
ring = torch.zeros((19, n), device=device, dtype=torch.uint8)
|
||||||
|
for name, width in (("drive", 2), ("state", 2), ("inhibition", 4064)):
|
||||||
|
maps["apl_" + name] = new_array(out_dir / ("apl-" + name + ".float32.npy"), np.float32, (steps, width))
|
||||||
|
if spec["record_history"]:
|
||||||
|
for name, dtype in (("v", np.float64), ("g", np.float64), ("ref", np.int32)):
|
||||||
|
maps[name] = new_array(out_dir / (name + "-history." + np.dtype(dtype).name + ".npy"), dtype, (steps, n))
|
||||||
|
maps["pre_" + name] = new_array(out_dir / ("preAPL-" + name + "." + np.dtype(dtype).name + ".npy"), dtype, (steps, n))
|
||||||
|
event_steps, event_nodes = [], []
|
||||||
|
accepted_requests_total, due_total, accepted_due_total = 0, 0, 0
|
||||||
|
queue_summary = queue_function()
|
||||||
|
simulation_start = time.perf_counter()
|
||||||
|
with (out_dir / "queue.jsonl").open("x", encoding="utf-8", buffering=1) as queue_output, \
|
||||||
|
(out_dir / "tick-state-hashes.jsonl").open("x", encoding="utf-8", buffering=1) as hash_output, \
|
||||||
|
(out_dir / "requests.csv").open("x", encoding="utf-8", newline="", buffering=1) as request_output:
|
||||||
|
writer = csv.DictWriter(request_output, fieldnames=REQUEST_FIELDS)
|
||||||
|
writer.writeheader()
|
||||||
|
for tick in range(steps):
|
||||||
|
requests.zero_()
|
||||||
|
begin, end = np.searchsorted(request_ticks, (tick, tick + 1))
|
||||||
|
if end > begin:
|
||||||
|
requested_local_gpu = upload(request_local[begin:end], torch.int64)
|
||||||
|
requests[requested_local_gpu] = 1
|
||||||
|
accepted = (ref[requested_local_gpu] <= 1).to(torch.uint8).cpu().numpy()
|
||||||
|
accepted_requests_total += int(accepted.sum())
|
||||||
|
writer.writerows({"tick": tick, "neuron_idx": int(node), "attempted": 1,
|
||||||
|
"accepted": int(ok), "rejected": 1 - int(ok)}
|
||||||
|
for node, ok in zip(request_nodes[begin:end], accepted))
|
||||||
|
spikes = ring[tick % 19]
|
||||||
|
ext.state_step(v, g, ref, requests, spikes, counts,
|
||||||
|
*[float(coeff[name]) for name in COEFFICIENT_NAMES], 22)
|
||||||
|
expanded_global = np.empty(0, dtype=np.int64)
|
||||||
|
accepted_cpu = np.empty(0, dtype=np.uint8)
|
||||||
|
if tick >= 18:
|
||||||
|
due = ring[(tick - 18) % 19]
|
||||||
|
sources = torch.nonzero(due, as_tuple=False).flatten().contiguous()
|
||||||
|
if sources.numel():
|
||||||
|
degrees = indptr[sources + 1] - indptr[sources]
|
||||||
|
offsets = (torch.cumsum(degrees, dim=0) - degrees).contiguous()
|
||||||
|
edge_count = int(degrees.sum().item())
|
||||||
|
expanded = torch.empty(edge_count, device=device, dtype=torch.int64)
|
||||||
|
ext.fill_edges(indptr, sources, offsets, expanded)
|
||||||
|
if edge_count:
|
||||||
|
destination = dst[expanded]
|
||||||
|
# Actual active fanout order, BEFORE stable target grouping.
|
||||||
|
expanded_global = graph["edge_id"][expanded.cpu().numpy()].copy()
|
||||||
|
accepted_cpu = (ref[destination.long()] == 0).to(torch.uint8).cpu().numpy().copy()
|
||||||
|
order = torch.argsort(destination, stable=True)
|
||||||
|
ordered_edges, ordered_targets = expanded[order].contiguous(), destination[order]
|
||||||
|
boundary = torch.ones(edge_count, device=device, dtype=torch.bool)
|
||||||
|
boundary[1:] = ordered_targets[1:] != ordered_targets[:-1]
|
||||||
|
starts = torch.nonzero(boundary, as_tuple=False).flatten().contiguous()
|
||||||
|
targets = ordered_targets[starts].contiguous()
|
||||||
|
ext.apply_arrivals(ordered_edges, starts, targets, weights, g, ref)
|
||||||
|
queue = queue_summary(tick, expanded_global, accepted_cpu)
|
||||||
|
queue_output.write(json.dumps(queue, allow_nan=False) + "\n")
|
||||||
|
due_total += queue["count"]
|
||||||
|
accepted_due_total += queue["accepted_count"]
|
||||||
|
if spec["record_history"]:
|
||||||
|
for name, value in (("v", v), ("g", g), ("ref", ref)):
|
||||||
|
maps["pre_" + name][tick] = value.cpu().numpy()
|
||||||
|
if n == N_NEURONS:
|
||||||
|
full_spikes = spikes
|
||||||
|
else:
|
||||||
|
apl.spikes.zero_()
|
||||||
|
apl.spikes[global_nodes_gpu] = spikes
|
||||||
|
full_spikes = apl.spikes
|
||||||
|
drive, apl_state, h = apl.advance(full_spikes)
|
||||||
|
# Mixed precision contract: widen f32 h EXACTLY, THEN multiply
|
||||||
|
# in f64, THEN subtract in f64. Do not guard refractory KCs.
|
||||||
|
delta_si = h[kc_full_gpu].to(torch.float64) * 0.001
|
||||||
|
g[kc_local_gpu] = g[kc_local_gpu] - delta_si
|
||||||
|
apl_cpu = {"drive": drive.cpu().numpy().copy(), "state": apl_state.cpu().numpy().copy(),
|
||||||
|
"inhibition": h.cpu().numpy().copy()}
|
||||||
|
for name, value in apl_cpu.items():
|
||||||
|
maps["apl_" + name][tick] = value
|
||||||
|
actual = {"v": v.cpu().numpy().copy(), "g": g.cpu().numpy().copy(),
|
||||||
|
"ref": ref.cpu().numpy().copy()}
|
||||||
|
finite = all(bool(np.isfinite(value).all()) for value in list(actual.values()) + list(apl_cpu.values()))
|
||||||
|
row = {"tick": tick, **{name + "_sha256": raw_hash(value, "<i4" if name == "ref" else "<f8")
|
||||||
|
for name, value in actual.items()}}
|
||||||
|
hash_output.write(json.dumps(row, allow_nan=False) + "\n")
|
||||||
|
if spec["record_history"]:
|
||||||
|
for name, value in actual.items():
|
||||||
|
maps[name][tick] = value
|
||||||
|
fired_local = torch.nonzero(spikes, as_tuple=False).flatten().cpu().numpy()
|
||||||
|
if len(fired_local):
|
||||||
|
event_steps.append(np.full(len(fired_local), tick, dtype=np.int32))
|
||||||
|
event_nodes.append(graph["nodes"][fired_local].copy())
|
||||||
|
completed += 1
|
||||||
|
if not finite:
|
||||||
|
with (out_dir / "first-failure-state.npz").open("xb") as target:
|
||||||
|
np.savez_compressed(target, tick=np.array(tick, dtype=np.int32), **actual,
|
||||||
|
**{"apl_" + name: value for name, value in apl_cpu.items()})
|
||||||
|
require(False, "Nonfinite state; first failure saved")
|
||||||
|
torch.cuda.synchronize(device)
|
||||||
|
|
||||||
|
def joined(values):
|
||||||
|
return np.concatenate(values).astype(np.int32, copy=False) if values else np.empty(0, dtype=np.int32)
|
||||||
|
|
||||||
|
state = {"step": joined(event_steps), "neuron_idx": joined(event_nodes), "counts": counts.cpu().numpy(),
|
||||||
|
"v": v.cpu().numpy(), "g": g.cpu().numpy(), "ref": ref.cpu().numpy()}
|
||||||
|
with (out_dir / "state.npz").open("xb") as target:
|
||||||
|
np.savez_compressed(target, **state)
|
||||||
|
event_locals = np.searchsorted(graph["nodes"], state["neuron_idx"])
|
||||||
|
counts_exact = np.array_equal(np.bincount(event_locals, minlength=n), state["counts"])
|
||||||
|
require(counts_exact and completed == steps, "Sparse events/counts/completed ticks mismatch")
|
||||||
|
for value in maps.values():
|
||||||
|
value.flush()
|
||||||
|
summary = {"case": spec["name"], "complete": True, "pass_all": True,
|
||||||
|
"pass_all_scope": "internal finite/recording/event-count integrity only; independent equivalence not claimed",
|
||||||
|
"steps": steps, "completed_ticks": completed, "nodes": n, "edges": e, "precision": "float64",
|
||||||
|
"apl_precision": "float32", "state_units": "SI volts", "total_spikes": len(state["step"]),
|
||||||
|
"requested": len(request_nodes), "accepted_requests": accepted_requests_total,
|
||||||
|
"rejected_requests": len(request_nodes) - accepted_requests_total,
|
||||||
|
"arriving_edges": due_total, "accepted_arriving_edges": accepted_due_total,
|
||||||
|
"counts_match_sparse_events": bool(counts_exact), "all_finite": True,
|
||||||
|
"record_history": spec["record_history"], "apl_fast_edges_zeroed": int(apl_out_mask.sum()),
|
||||||
|
"kc_targets_present": len(common_kc), "effective_weights_raw_sha256": effective_hash.hexdigest(),
|
||||||
|
"apl_component": apl.metadata, "apl_schedule": "end, after threshold/reset and guarded arrivals, unconditional all KC",
|
||||||
|
"apl_si_conversion": "h32 -> float64 -> multiply float64 0.001 -> separate float64 subtraction",
|
||||||
|
"build": build, "sealed_ae_backend_sha256": file_sha256(AE_MODEL / "gpu_backend.py"),
|
||||||
|
"shared_apl_component_oracle_limitation": True, "oracle_validation_claim": False,
|
||||||
|
"learning": False, "performance_runtime_claim": False, "cpu_sync_each_tick": True,
|
||||||
|
"build_or_cache_seconds": build_done - start,
|
||||||
|
"diagnostic_simulation_seconds": time.perf_counter() - simulation_start,
|
||||||
|
"wall_seconds": time.perf_counter() - start,
|
||||||
|
"peak_allocated_vram_bytes": int(torch.cuda.max_memory_allocated(device)),
|
||||||
|
"peak_reserved_vram_bytes": int(torch.cuda.max_memory_reserved(device)),
|
||||||
|
"input_sha256": {"spec.json": file_sha256(case_dir / "spec.json"),
|
||||||
|
"requests.npz": file_sha256(case_dir / "requests.npz"),
|
||||||
|
"base_weights.npy": file_sha256(Path(spec["graph_dir"]) / "weights.npy"),
|
||||||
|
"coefficients.json": file_sha256(spec["coefficients_path"])}}
|
||||||
|
if (case_dir / "arrays.npz").exists():
|
||||||
|
summary["input_sha256"]["arrays.npz"] = file_sha256(case_dir / "arrays.npz")
|
||||||
|
write_json(out_dir / "summary.json", summary)
|
||||||
|
return summary
|
||||||
|
except Exception as error:
|
||||||
|
for value in maps.values():
|
||||||
|
value.flush()
|
||||||
|
write_json(out_dir / "error.json", {"complete": False, "pass_all": False,
|
||||||
|
"tick_in_progress": tick, "completed_ticks": completed,
|
||||||
|
"type": type(error).__name__, "message": str(error), "traceback": traceback.format_exc()})
|
||||||
|
raise
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
"""Frozen eager Torch float32 APL component and binary oracle sidecar.
|
||||||
|
|
||||||
|
This is the Phase 4P operator sequence, not an author-neuron implementation.
|
||||||
|
No precision/determinism flags are changed here. The full matrix dimensions
|
||||||
|
are retained even when the caller simulates a small neuronal fixture.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import torch
|
||||||
|
|
||||||
|
|
||||||
|
PROTOCOL = "phase4ag-apl-v1"
|
||||||
|
N_NEURONS, N_APL, N_KC = 166700, 2, 4064
|
||||||
|
BUNDLE_FILES = ("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")
|
||||||
|
FRAME = struct.Struct("<qQ")
|
||||||
|
PAYLOAD_BYTES = (N_APL + N_APL + N_KC) * 4
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def file_sha256(path):
|
||||||
|
digest = hashlib.sha256()
|
||||||
|
with Path(path).open("rb") as stream:
|
||||||
|
for block in iter(lambda: stream.read(8 << 20), b""):
|
||||||
|
digest.update(block)
|
||||||
|
return digest.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def array_sha256(value):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def environment_metadata():
|
||||||
|
device = torch.cuda.current_device()
|
||||||
|
return {"torch": str(torch.__version__), "numpy": str(np.__version__),
|
||||||
|
"cuda": torch.version.cuda, "cudnn": torch.backends.cudnn.version(),
|
||||||
|
"device_name": torch.cuda.get_device_name(device), "device_index": device,
|
||||||
|
"device_capability": list(torch.cuda.get_device_capability(device)),
|
||||||
|
"deterministic_algorithms": torch.are_deterministic_algorithms_enabled(),
|
||||||
|
"cudnn_deterministic": torch.backends.cudnn.deterministic,
|
||||||
|
"cudnn_benchmark": torch.backends.cudnn.benchmark,
|
||||||
|
"cuda_matmul_allow_tf32": torch.backends.cuda.matmul.allow_tf32,
|
||||||
|
"cudnn_allow_tf32": torch.backends.cudnn.allow_tf32,
|
||||||
|
"float32_matmul_precision": torch.get_float32_matmul_precision(),
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": os.environ.get("CUBLAS_WORKSPACE_CONFIG"),
|
||||||
|
"precision_configuration_changed_by_component": False}
|
||||||
|
|
||||||
|
|
||||||
|
class LegacyAPL:
|
||||||
|
"""Independent zero-initialized APL state with original full-width matrices."""
|
||||||
|
|
||||||
|
def __init__(self, bundle_dir, dt_ms):
|
||||||
|
require(float(dt_ms) == 0.1, "Only frozen dt_ms=0.1 is allowed")
|
||||||
|
require(torch.cuda.is_available(), "CUDA is required for the legacy Torch component")
|
||||||
|
self.bundle_dir = Path(bundle_dir)
|
||||||
|
expected = {"input_matrix.npy": (np.float32, (N_APL, N_NEURONS)),
|
||||||
|
"output_matrix.npy": (np.float32, (N_APL, N_KC)),
|
||||||
|
"kc_globals.npy": (np.int32, (N_KC,)),
|
||||||
|
"apl_globals.npy": (np.int32, (N_APL,))}
|
||||||
|
arrays = {}
|
||||||
|
for name, (dtype, shape) in expected.items():
|
||||||
|
value = np.load(self.bundle_dir / name, allow_pickle=False)
|
||||||
|
require(value.dtype == dtype and value.shape == shape and value.flags.c_contiguous,
|
||||||
|
"APL bundle dtype/shape/layout mismatch: " + name)
|
||||||
|
require(bool(np.isfinite(value).all()), "Nonfinite APL bundle: " + name)
|
||||||
|
arrays[name] = value
|
||||||
|
for name in ("kc_globals.npy", "apl_globals.npy"):
|
||||||
|
ids = arrays[name]
|
||||||
|
require(bool(np.all((ids >= 0) & (ids < N_NEURONS))) and
|
||||||
|
bool(np.all(np.diff(ids) > 0)), "APL/KC globals must be sorted unique: " + name)
|
||||||
|
require(not np.intersect1d(arrays["kc_globals.npy"], arrays["apl_globals.npy"]).size,
|
||||||
|
"APL and KC identities overlap")
|
||||||
|
require(bool(np.all(arrays["input_matrix.npy"] >= 0)) and
|
||||||
|
bool(np.all(arrays["output_matrix.npy"] >= 0)), "APL raw-contact matrices must be nonnegative")
|
||||||
|
self.device = torch.device("cuda", torch.cuda.current_device())
|
||||||
|
self.input_gpu = torch.from_numpy(arrays["input_matrix.npy"].copy()).to(self.device)
|
||||||
|
self.output_gpu = torch.from_numpy(arrays["output_matrix.npy"].copy()).to(self.device)
|
||||||
|
self.kc_globals = arrays["kc_globals.npy"].copy()
|
||||||
|
self.apl_globals = arrays["apl_globals.npy"].copy()
|
||||||
|
self.state = torch.zeros(N_APL, dtype=torch.float32, device=self.device)
|
||||||
|
self.spikes = torch.zeros(N_NEURONS, dtype=torch.uint8, device=self.device)
|
||||||
|
self.decay = np.float32(math.exp(-float(dt_ms) / 20.0))
|
||||||
|
self.gain = np.float32(0.01)
|
||||||
|
self.metadata = {"ok": True, "protocol": PROTOCOL, "n_neurons": N_NEURONS,
|
||||||
|
"n_apl": N_APL, "n_kc": N_KC, "dt_ms": float(dt_ms),
|
||||||
|
"files_sha256": {name: file_sha256(self.bundle_dir / name) for name in BUNDLE_FILES},
|
||||||
|
"array_sha256": {name: array_sha256(value) for name, value in arrays.items()},
|
||||||
|
"decay_f32_bits": f"{int(self.decay.view(np.uint32)):08x}",
|
||||||
|
"gain_f32_bits": f"{int(self.gain.view(np.uint32)):08x}",
|
||||||
|
"environment": environment_metadata(),
|
||||||
|
"operator_sequence": "state.mul_(decay32); drive=mv(I32,spikes32); state.add_(drive); h=matmul(state,O32)*gain32",
|
||||||
|
"h_units": "legacy mV", "initial_state": "float32 zeros"}
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
def advance(self, spikes_u8):
|
||||||
|
require(spikes_u8.device == self.device and spikes_u8.dtype == torch.uint8 and
|
||||||
|
tuple(spikes_u8.shape) == (N_NEURONS,) and spikes_u8.is_contiguous(),
|
||||||
|
"APL expects full-width contiguous CUDA uint8 spikes")
|
||||||
|
# Preserve separate eager operations, including Python evaluation order
|
||||||
|
# in the frozen state.mul_(...).add_(torch.mv(...)) expression.
|
||||||
|
self.state.mul_(float(self.decay))
|
||||||
|
drive = torch.mv(self.input_gpu, spikes_u8.to(torch.float32))
|
||||||
|
self.state.add_(drive)
|
||||||
|
h = torch.matmul(self.state, self.output_gpu) * self.gain
|
||||||
|
return drive, self.state, h
|
||||||
|
|
||||||
|
def advance_global_fired(self, fired):
|
||||||
|
require(fired.dtype == np.int32 and fired.ndim == 1, "Global spikes must be int32 vector")
|
||||||
|
require(bool(np.all((fired >= 0) & (fired < N_NEURONS))) and
|
||||||
|
bool(np.all(np.diff(fired) > 0)), "Global spikes must be sorted unique and in range")
|
||||||
|
self.spikes.zero_()
|
||||||
|
if fired.size:
|
||||||
|
indices = torch.from_numpy(fired.copy()).to(device=self.device, dtype=torch.int64)
|
||||||
|
self.spikes[indices] = 1
|
||||||
|
return self.advance(self.spikes)
|
||||||
|
|
||||||
|
|
||||||
|
def read_exact(stream, count, boundary_eof=False):
|
||||||
|
result = bytearray()
|
||||||
|
while len(result) < count:
|
||||||
|
block = stream.read(count - len(result))
|
||||||
|
if not block:
|
||||||
|
if boundary_eof and not result:
|
||||||
|
return None
|
||||||
|
raise EOFError("Truncated APL request frame")
|
||||||
|
result.extend(block)
|
||||||
|
return bytes(result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--bundle-dir", required=True)
|
||||||
|
parser.add_argument("--dt-ms", required=True, type=float)
|
||||||
|
args = parser.parse_args()
|
||||||
|
# stdout is exclusively the handshake line and binary response frames.
|
||||||
|
output, source = sys.stdout.buffer, sys.stdin.buffer
|
||||||
|
component = LegacyAPL(args.bundle_dir, args.dt_ms)
|
||||||
|
output.write((json.dumps(component.metadata, allow_nan=False) + "\n").encode("utf-8"))
|
||||||
|
output.flush()
|
||||||
|
expected_tick = 0
|
||||||
|
while True:
|
||||||
|
header = read_exact(source, FRAME.size, boundary_eof=True)
|
||||||
|
if header is None:
|
||||||
|
return
|
||||||
|
tick, count = FRAME.unpack(header)
|
||||||
|
require(tick == expected_tick and count <= N_NEURONS, "Invalid APL request tick/count")
|
||||||
|
fired = np.frombuffer(read_exact(source, count * 4), dtype="<i4").copy()
|
||||||
|
drive, state, h = component.advance_global_fired(fired)
|
||||||
|
arrays = [value.detach().cpu().numpy().astype("<f4", copy=False) for value in (drive, state, h)]
|
||||||
|
require(all(bool(np.isfinite(value).all()) for value in arrays), "Nonfinite APL output")
|
||||||
|
output.write(FRAME.pack(tick, PAYLOAD_BYTES))
|
||||||
|
for value in arrays:
|
||||||
|
output.write(value.tobytes())
|
||||||
|
output.flush()
|
||||||
|
expected_tick += 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"root": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v1",
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "PROTOCOL.md",
|
||||||
|
"bytes": 5033,
|
||||||
|
"sha256": "c14c2d3c35e2b404c516befa66370723fba075516540214ae46e4104ff87e813"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "calibration.py",
|
||||||
|
"bytes": 25414,
|
||||||
|
"sha256": "edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "compare.py",
|
||||||
|
"bytes": 33632,
|
||||||
|
"sha256": "6e1616b086f667fa4e4b5087f500f8080281977ca9922e7b055acfddd2003bd5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "config.json",
|
||||||
|
"bytes": 1845,
|
||||||
|
"sha256": "2aa6b4d777ff698018e1a6eaf571215208b8c874a4c848a6d632e2bd778c90e3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "context.py",
|
||||||
|
"bytes": 2038,
|
||||||
|
"sha256": "b8b1231d958a3ec935ec1d5a36e08cbd9bcd1127f4d4bb243a9051884a0e7a16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "finalize.py",
|
||||||
|
"bytes": 6747,
|
||||||
|
"sha256": "b6e3c67e668a971b544df32d76435ab5e537061b9fc2e8d9dedb5d2a726f5782"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "gpu_apl.py",
|
||||||
|
"bytes": 21206,
|
||||||
|
"sha256": "69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "legacy_apl_worker.py",
|
||||||
|
"bytes": 8158,
|
||||||
|
"sha256": "21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "oracle_apl.py",
|
||||||
|
"bytes": 46017,
|
||||||
|
"sha256": "9b7f3e0b59f2117b94b41a6f542f37e6f7950138d324c905e8e0ac6cb7d17151"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "prepare.py",
|
||||||
|
"bytes": 13633,
|
||||||
|
"sha256": "197ccc6aae70566c4db4d4de17fa032e853b9bd9a04262905d6c71e12a930b6f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "run_case.py",
|
||||||
|
"bytes": 2116,
|
||||||
|
"sha256": "afbe6d5a37c29bda66d38c470093584130d1852e67881c681662aec3c76b33c7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "run_suite.py",
|
||||||
|
"bytes": 3700,
|
||||||
|
"sha256": "84c681030b0032119b5392d0c3f3c136a9c6b0d133eb548c40791a10bbbb8b63"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "test_calibration.py",
|
||||||
|
"bytes": 8127,
|
||||||
|
"sha256": "bab3136eecbc5bb09a985d715844ee845cb72b07930ce376bfb39be33bd1845a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "test_protocol.py",
|
||||||
|
"bytes": 11764,
|
||||||
|
"sha256": "1a233f47943e01bbd845ac1dacdb1eec3f88c270c65a5f75bce1cf679b5de097"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "validate_components.py",
|
||||||
|
"bytes": 24824,
|
||||||
|
"sha256": "5cfc9a4505da6b8fb4e7d2617cdaedaa8475ed46a11ec9bdf0d4d25b1d22c2d3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "verify_frozen.py",
|
||||||
|
"bytes": 2160,
|
||||||
|
"sha256": "0d0e72b2f1348f6648124c8c34f75094f76fc5e1a281fbcca130a5fad2f35293"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,740 @@
|
|||||||
|
"""Phase 4AG shared-APL-component closed-loop Brian oracle.
|
||||||
|
|
||||||
|
Brian has no Torch dependency. A separate, pinned science-Python process
|
||||||
|
executes the unchanged legacy float32 APL operations from Brian's own spikes.
|
||||||
|
This is independent LIF/scheduling validation with a shared APL numerical
|
||||||
|
component, NOT an all-components-independent CPU oracle.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import importlib.metadata
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import queue
|
||||||
|
import struct
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import types
|
||||||
|
from contextlib import ExitStack
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
BLOCK_BYTES = 8 << 20
|
||||||
|
PROTOCOL = "phase4ag-apl-v1"
|
||||||
|
AUTHOR_PATH = Path("/data/digital-drosophila/experiments/phase4ad-author-semantics/external-resources/model.py")
|
||||||
|
AUTHOR_SHA256 = "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e"
|
||||||
|
AE_PATH = Path("/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/oracle_stress.py")
|
||||||
|
AE_SHA256 = "32eb1c42383068ce52701d2139a376ce155ad7072cde019949f8ca2d55492409"
|
||||||
|
AF_PATH = Path("/data/digital-drosophila/models/male-cns-lif/author-fullgraph-lab-v1/oracle_full.py")
|
||||||
|
AF_SHA256 = "d72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961"
|
||||||
|
EVENT_DTYPE = np.dtype([("step", "<i4"), ("neuron_idx", "<i4")])
|
||||||
|
BUNDLE_FILES = ("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")
|
||||||
|
_PROCESS_USED = False
|
||||||
|
|
||||||
|
|
||||||
|
def _check(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def _save(path, value):
|
||||||
|
with Path(path).open("x", encoding="utf-8") as handle:
|
||||||
|
json.dump(value, handle, indent=2, sort_keys=True, allow_nan=False)
|
||||||
|
handle.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def _digest(path):
|
||||||
|
result = hashlib.sha256()
|
||||||
|
with Path(path).open("rb") as handle:
|
||||||
|
for block in iter(lambda: handle.read(BLOCK_BYTES), b""):
|
||||||
|
result.update(block)
|
||||||
|
return result.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _array_hash(array, dtype):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(array, dtype=dtype).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _load_checked(path, expected, name):
|
||||||
|
data = Path(path).read_bytes()
|
||||||
|
_check(hashlib.sha256(data).hexdigest() == expected, f"Pinned source hash mismatch: {path}")
|
||||||
|
module = types.ModuleType(name)
|
||||||
|
module.__file__ = str(path)
|
||||||
|
exec(compile(data, str(path), "exec"), module.__dict__)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
def _new_memmap(path, dtype, shape):
|
||||||
|
_check(not Path(path).exists(), f"Refusing to overwrite output: {path}")
|
||||||
|
return np.lib.format.open_memmap(path, mode="w+", dtype=dtype, shape=shape)
|
||||||
|
|
||||||
|
|
||||||
|
def _budget(root, limit, reserve=0):
|
||||||
|
total = 0
|
||||||
|
for directory, _, filenames in os.walk(root, followlinks=False):
|
||||||
|
for filename in filenames:
|
||||||
|
total += (Path(directory) / filename).stat(follow_symlinks=False).st_size
|
||||||
|
_check(total + int(reserve) <= limit,
|
||||||
|
f"Output budget exceeded: {total}+{reserve}>{limit}; inputs and duration were not adjusted")
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
class _PipeReader:
|
||||||
|
"""One bounded reader thread, with timeout/EOF checks for every frame."""
|
||||||
|
|
||||||
|
def __init__(self, pipe, timeout):
|
||||||
|
self.pipe, self.timeout = pipe, float(timeout)
|
||||||
|
self.chunks = queue.Queue(maxsize=8)
|
||||||
|
self.buffer = bytearray()
|
||||||
|
self.thread = threading.Thread(target=self._pump, daemon=True)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def _pump(self):
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
chunk = os.read(self.pipe.fileno(), 65536)
|
||||||
|
self.chunks.put(chunk)
|
||||||
|
if not chunk:
|
||||||
|
return
|
||||||
|
except BaseException as error:
|
||||||
|
self.chunks.put(error)
|
||||||
|
|
||||||
|
def _fill(self, deadline):
|
||||||
|
remaining = deadline - time.monotonic()
|
||||||
|
if remaining <= 0:
|
||||||
|
raise TimeoutError("APL sidecar response timed out")
|
||||||
|
try:
|
||||||
|
chunk = self.chunks.get(timeout=remaining)
|
||||||
|
except queue.Empty as error:
|
||||||
|
raise TimeoutError("APL sidecar response timed out") from error
|
||||||
|
if isinstance(chunk, BaseException):
|
||||||
|
raise RuntimeError("APL sidecar stdout reader failed") from chunk
|
||||||
|
if not chunk:
|
||||||
|
raise EOFError("APL sidecar ended before a complete response")
|
||||||
|
self.buffer.extend(chunk)
|
||||||
|
|
||||||
|
def read(self, size):
|
||||||
|
deadline = time.monotonic() + self.timeout
|
||||||
|
while len(self.buffer) < size:
|
||||||
|
self._fill(deadline)
|
||||||
|
result = bytes(self.buffer[:size])
|
||||||
|
del self.buffer[:size]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def line(self):
|
||||||
|
deadline = time.monotonic() + self.timeout
|
||||||
|
while b"\n" not in self.buffer:
|
||||||
|
_check(len(self.buffer) < 1 << 20, "APL sidecar handshake exceeds 1 MiB")
|
||||||
|
self._fill(deadline)
|
||||||
|
end = self.buffer.index(b"\n") + 1
|
||||||
|
result = bytes(self.buffer[:end])
|
||||||
|
del self.buffer[:end]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class _APLWorker:
|
||||||
|
def __init__(self, python, script, bundle_dir, stderr, timeout=180):
|
||||||
|
self.command = [str(python), "-B", str(script), "--bundle-dir", str(bundle_dir), "--dt-ms", "0.1"]
|
||||||
|
self.process = subprocess.Popen(self.command, stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE, stderr=stderr, bufsize=0, shell=False)
|
||||||
|
self.reader = _PipeReader(self.process.stdout, timeout)
|
||||||
|
self.tick = 0
|
||||||
|
try:
|
||||||
|
self.hello = json.loads(self.reader.line().decode("utf-8"))
|
||||||
|
_check(self.hello.get("ok") is True, "APL sidecar did not acknowledge initialization")
|
||||||
|
_check(self.hello.get("protocol") == PROTOCOL, "Unexpected APL sidecar protocol")
|
||||||
|
for key, value in (("n_neurons", 166700), ("n_apl", 2), ("n_kc", 4064)):
|
||||||
|
_check(self.hello.get(key) == value, f"APL sidecar changed {key}")
|
||||||
|
_check(self.hello.get("dt_ms") == .1, "APL sidecar changed dt")
|
||||||
|
expected_decay = f"{int(np.float32(math.exp(-.1 / 20.)).view(np.uint32)):08x}"
|
||||||
|
expected_gain = f"{int(np.float32(.01).view(np.uint32)):08x}"
|
||||||
|
_check(self.hello.get("decay_f32_bits") == expected_decay and self.hello.get("gain_f32_bits") == expected_gain,
|
||||||
|
"APL sidecar decay/gain differs from the frozen float32 scalars")
|
||||||
|
_check(self.hello.get("files_sha256") == {name: _digest(bundle_dir / name) for name in BUNDLE_FILES},
|
||||||
|
"APL sidecar bundle hashes differ from the independently read bundle")
|
||||||
|
except BaseException:
|
||||||
|
self.abort()
|
||||||
|
raise
|
||||||
|
|
||||||
|
def step(self, tick, global_spikes):
|
||||||
|
_check(tick == self.tick, "APL sidecar request ticks must be consecutive")
|
||||||
|
nodes = np.asarray(global_spikes)
|
||||||
|
_check(nodes.ndim == 1 and nodes.dtype == np.dtype("int32"), "APL input spikes must be int32 globals")
|
||||||
|
_check(not len(nodes) or (nodes[0] >= 0 and nodes[-1] < 166700 and np.all(np.diff(nodes) > 0)),
|
||||||
|
"APL input spikes must be sorted, unique, and in the frozen global range")
|
||||||
|
packet = struct.pack("<qQ", int(tick), len(nodes)) + np.ascontiguousarray(nodes, dtype="<i4").tobytes()
|
||||||
|
view = memoryview(packet)
|
||||||
|
while view:
|
||||||
|
written = self.process.stdin.write(view)
|
||||||
|
if not written:
|
||||||
|
raise BrokenPipeError("APL sidecar stdin failed")
|
||||||
|
view = view[written:]
|
||||||
|
self.process.stdin.flush()
|
||||||
|
response_tick, byte_count = struct.unpack("<qQ", self.reader.read(16))
|
||||||
|
_check(response_tick == tick and byte_count == (2 + 2 + 4064) * 4,
|
||||||
|
"APL sidecar frame tick/length mismatch")
|
||||||
|
values = np.frombuffer(self.reader.read(byte_count), dtype="<f4")
|
||||||
|
_check(np.isfinite(values).all() and np.all(values >= 0), "APL sidecar returned invalid nonnegative f32 states")
|
||||||
|
self.tick += 1
|
||||||
|
return values[:2], values[2:4], values[4:]
|
||||||
|
|
||||||
|
def finish(self, steps):
|
||||||
|
_check(self.tick == steps, "APL sidecar did not process every tick")
|
||||||
|
self.process.stdin.close()
|
||||||
|
status = self.process.wait(timeout=30)
|
||||||
|
_check(status == 0, f"APL sidecar exited unsuccessfully: {status}")
|
||||||
|
self.reader.thread.join(timeout=5)
|
||||||
|
_check(not self.reader.thread.is_alive(), "APL stdout did not reach EOF")
|
||||||
|
extra = bytes(self.reader.buffer)
|
||||||
|
while not self.reader.chunks.empty():
|
||||||
|
chunk = self.reader.chunks.get_nowait()
|
||||||
|
_check(not isinstance(chunk, BaseException), "APL stdout reader failed after the last frame")
|
||||||
|
extra += chunk
|
||||||
|
_check(not extra, "APL sidecar emitted unrequested trailing stdout bytes")
|
||||||
|
self.process.stdout.close()
|
||||||
|
return status
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
if self.process.poll() is None:
|
||||||
|
self.process.terminate()
|
||||||
|
try:
|
||||||
|
self.process.wait(timeout=5)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
self.process.kill()
|
||||||
|
self.process.wait(timeout=5)
|
||||||
|
for handle in (self.process.stdin, self.process.stdout):
|
||||||
|
if handle is not None and not handle.closed:
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
|
||||||
|
def _graph_inputs(directory):
|
||||||
|
arrays = {}
|
||||||
|
definitions = {"nodes": "int32", "edge_id": "int64", "src": "int32",
|
||||||
|
"dst": "int32", "signed_raw": "int64", "ptr": "int64", "weights": "float64"}
|
||||||
|
for name, dtype in definitions.items():
|
||||||
|
value = np.load(directory / (name + ".npy"), mmap_mode="r", allow_pickle=False)
|
||||||
|
_check(value.ndim == 1 and value.dtype == np.dtype(dtype), f"Invalid graph array {name}")
|
||||||
|
arrays[name] = value
|
||||||
|
nodes, edge_ids = arrays["nodes"], arrays["edge_id"]
|
||||||
|
n, edges = len(nodes), len(edge_ids)
|
||||||
|
_check(0 < n <= 166700 and edges > 0, "A case needs real global nodes and explicit nonempty connectivity")
|
||||||
|
_check(nodes[0] >= 0 and nodes[-1] < 166700 and np.all(np.diff(nodes) > 0), "Invalid global node order")
|
||||||
|
for name in ("src", "dst", "signed_raw", "weights"):
|
||||||
|
_check(arrays[name].shape == (edges,), f"Graph array {name} has the wrong shape")
|
||||||
|
pointer = arrays["ptr"]
|
||||||
|
_check(pointer.shape == (n + 1,) and pointer[0] == 0 and pointer[-1] == edges and
|
||||||
|
np.all(np.diff(pointer) >= 0), "Invalid graph CSR pointer")
|
||||||
|
source_counts = np.zeros(n, np.int64)
|
||||||
|
identity_edges = True
|
||||||
|
previous_source, previous_edge = -1, -1
|
||||||
|
width = BLOCK_BYTES // 8
|
||||||
|
for begin in range(0, edges, width):
|
||||||
|
stop = min(edges, begin + width)
|
||||||
|
source, target, ids = arrays["src"][begin:stop], arrays["dst"][begin:stop], edge_ids[begin:stop]
|
||||||
|
_check(np.all((source >= 0) & (source < n)) and np.all((target >= 0) & (target < n)),
|
||||||
|
"Graph edge endpoint is outside the local node array")
|
||||||
|
_check(np.all(ids >= 0), "Graph edge IDs must be nonnegative")
|
||||||
|
_check(source[0] > previous_source or (source[0] == previous_source and ids[0] > previous_edge),
|
||||||
|
"Graph edge blocks are not in canonical source/edge order")
|
||||||
|
_check(np.all((source[1:] > source[:-1]) |
|
||||||
|
((source[1:] == source[:-1]) & (ids[1:] > ids[:-1]))),
|
||||||
|
"Graph edges are not in canonical source/edge order")
|
||||||
|
previous_source, previous_edge = int(source[-1]), int(ids[-1])
|
||||||
|
identity_edges &= np.array_equal(ids, np.arange(begin, stop, dtype=np.int64))
|
||||||
|
source_counts += np.bincount(source, minlength=n)
|
||||||
|
_check(np.isfinite(arrays["weights"][begin:stop]).all(), "Nonfinite graph weights")
|
||||||
|
_check(np.array_equal(source_counts, np.diff(pointer)), "CSR pointer and source rows disagree")
|
||||||
|
if not identity_edges:
|
||||||
|
_check(len(np.unique(edge_ids)) == edges, "Original edge IDs must be unique")
|
||||||
|
for name in ("completeness.csv", "connectivity.parquet"):
|
||||||
|
_check((directory / name).is_file(), f"Missing unchanged author input: {name}")
|
||||||
|
if n == 166700:
|
||||||
|
_check(edges == 25582938 and identity_edges and np.array_equal(nodes, np.arange(n, dtype=np.int32)),
|
||||||
|
"A full probe must use the unchanged complete canonical graph")
|
||||||
|
return arrays, identity_edges
|
||||||
|
|
||||||
|
|
||||||
|
def _requests(case_dir, nodes, steps):
|
||||||
|
with np.load(case_dir / "requests.npz", allow_pickle=False) as archive:
|
||||||
|
_check(set(archive.files) == {"tick", "neuron_idx"}, "Unexpected sparse request schema")
|
||||||
|
ticks, requested = archive["tick"].copy(), archive["neuron_idx"].copy()
|
||||||
|
_check(ticks.dtype == requested.dtype == np.dtype("int32") and ticks.ndim == requested.ndim == 1 and
|
||||||
|
ticks.shape == requested.shape, "Requests must be equal-length int32 vectors")
|
||||||
|
_check(np.all((ticks >= 0) & (ticks < steps)), "Request time outside the case")
|
||||||
|
_check(not len(ticks) or np.all((ticks[1:] > ticks[:-1]) |
|
||||||
|
((ticks[1:] == ticks[:-1]) & (requested[1:] > requested[:-1]))),
|
||||||
|
"Requests must be sorted and unique by tick/global node")
|
||||||
|
local = np.searchsorted(nodes, requested)
|
||||||
|
_check(np.all(local < len(nodes)) and np.array_equal(nodes[local], requested),
|
||||||
|
"Request references a global neuron absent from this case")
|
||||||
|
counts = np.bincount(ticks, minlength=steps).astype(np.int32)
|
||||||
|
pointer = np.concatenate((np.zeros(1, np.int64), np.cumsum(counts, dtype=np.int64)))
|
||||||
|
return requested, local.astype(np.int32), pointer, counts
|
||||||
|
|
||||||
|
|
||||||
|
class _QueueProxy:
|
||||||
|
def __init__(self, original, get_tick, available, arrays, identity_edges,
|
||||||
|
due_counts, spike_ring, delay_steps, handle, records, summarize):
|
||||||
|
self._original_queue, self._get_tick = original, get_tick
|
||||||
|
self._available, self._arrays, self._identity_edges = available, arrays, identity_edges
|
||||||
|
self._due_counts, self._spike_ring, self._delay_steps = due_counts, spike_ring, delay_steps
|
||||||
|
self._handle, self._records, self._summarize = handle, records, summarize
|
||||||
|
|
||||||
|
def peek(self, *args, **kwargs):
|
||||||
|
original = self._original_queue.peek(*args, **kwargs)
|
||||||
|
local_edges = np.asarray(original)
|
||||||
|
tick = self._get_tick()
|
||||||
|
_check(tick == len(self._records["rows"]), "Queue peek ticks must be consecutive")
|
||||||
|
_check(local_edges.ndim == 1 and np.all((local_edges >= 0) & (local_edges < len(self._arrays["edge_id"]))),
|
||||||
|
"Original queue contains an invalid local edge index")
|
||||||
|
_check(len(local_edges) == self._due_counts[tick % len(self._due_counts)],
|
||||||
|
"Queue arrivals differ from the fixed-delay outgoing degree of actual spikes")
|
||||||
|
fired_then = np.zeros(len(self._arrays["nodes"]), dtype=bool)
|
||||||
|
if tick >= self._delay_steps:
|
||||||
|
fired_then[self._spike_ring[(tick - self._delay_steps) % len(self._spike_ring)]] = True
|
||||||
|
|
||||||
|
def accepted(begin, stop):
|
||||||
|
part = local_edges[begin:stop]
|
||||||
|
_check(np.all(fired_then[self._arrays["src"][part]]), "Arrival lacks a presynaptic spike at author delay")
|
||||||
|
return self._available[self._arrays["dst"][part]]
|
||||||
|
|
||||||
|
# Only the observed ID view changes; the queue is returned verbatim.
|
||||||
|
edge_ids = local_edges if self._identity_edges else self._arrays["edge_id"][local_edges]
|
||||||
|
summary = self._summarize(tick, edge_ids, accepted)
|
||||||
|
self._handle.write(json.dumps(summary, sort_keys=True) + "\n")
|
||||||
|
self._records["rows"].append(summary)
|
||||||
|
self._records["peek_calls"] += 1
|
||||||
|
return original
|
||||||
|
|
||||||
|
def advance(self, *args, **kwargs):
|
||||||
|
self._records["advance_calls"] += 1
|
||||||
|
return self._original_queue.advance(*args, **kwargs)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self._original_queue, name)
|
||||||
|
|
||||||
|
|
||||||
|
def run_case(case_dir: Path, out_dir: Path) -> dict:
|
||||||
|
"""Run one continuous case, with exclusive outputs and no candidate trace input.
|
||||||
|
|
||||||
|
Graph inputs are the AF array/author-table schema plus original weights.npy.
|
||||||
|
requests.npz contains sparse tick/neuron_idx int32 vectors. Optional
|
||||||
|
arrays.npz contains initial_v_mv/initial_g_mv float64 vectors only.
|
||||||
|
Full probes write state hashes, sparse events and APL traces, not dense
|
||||||
|
whole-brain histories. Each case requires a fresh process.
|
||||||
|
"""
|
||||||
|
global _PROCESS_USED
|
||||||
|
_check(not _PROCESS_USED, "Every oracle case requires a fresh process")
|
||||||
|
_PROCESS_USED = True
|
||||||
|
case_dir, out_dir = Path(case_dir).resolve(strict=True), Path(out_dir).resolve()
|
||||||
|
spec = json.loads((case_dir / "spec.json").read_text(encoding="utf-8"))
|
||||||
|
graph_dir = Path(spec["graph_dir"]).resolve(strict=True)
|
||||||
|
bundle_dir = Path(spec["apl_bundle_dir"]).resolve(strict=True)
|
||||||
|
worker_path = Path(spec["legacy_apl_worker"]).resolve(strict=True)
|
||||||
|
science_python = Path(spec["science_python"]).resolve(strict=True)
|
||||||
|
author_path = Path(spec.get("author_path", AUTHOR_PATH)).resolve(strict=True)
|
||||||
|
ae_path = Path(spec.get("ae_oracle_path", AE_PATH)).resolve(strict=True)
|
||||||
|
af_path = Path(spec.get("af_oracle_path", AF_PATH)).resolve(strict=True)
|
||||||
|
coefficients_path = Path(spec["coefficients_path"]).resolve(strict=True)
|
||||||
|
steps = int(spec["steps"])
|
||||||
|
_check(steps == spec["steps"] and 0 < steps <= np.iinfo(np.int32).max, "Invalid number of steps")
|
||||||
|
_check(float(spec["dt_ms"]) == .1 and np.isclose(float(spec["duration_ms"]), steps * .1, rtol=0, atol=1e-12),
|
||||||
|
"The frozen APL protocol requires dt_ms=0.1 and a matching duration")
|
||||||
|
_check(spec.get("precision", "float64") == "float64", "Author state must be float64")
|
||||||
|
_check(spec.get("training", False) is False and spec.get("poi_used", False) is False,
|
||||||
|
"Training and original poi are outside this gate")
|
||||||
|
_check(spec["apl"] == {"tau_ms": 20, "gain": .01, "normalization": 1}, "Frozen APL parameters changed")
|
||||||
|
record_history = spec["record_history"]
|
||||||
|
_check(isinstance(record_history, bool), "record_history must be a boolean")
|
||||||
|
budget_root = Path(spec.get("budget_root", out_dir.parent)).resolve()
|
||||||
|
budget_limit = int(spec.get("output_budget_bytes", 15 * 1024 ** 3))
|
||||||
|
_check(budget_limit > 0 and out_dir.is_relative_to(budget_root), "Invalid output budget/root")
|
||||||
|
out_dir.mkdir(parents=True, exist_ok=False)
|
||||||
|
mapped_files = []
|
||||||
|
saved_preferences, old_dt, worker = None, None, None
|
||||||
|
last_complete_tick = -1
|
||||||
|
try:
|
||||||
|
arrays, identity_edges = _graph_inputs(graph_dir)
|
||||||
|
nodes, n, edges = arrays["nodes"], len(arrays["nodes"]), len(arrays["edge_id"])
|
||||||
|
_check(n < 166700 or not record_history, "Full probes must not save dense V/g/ref histories")
|
||||||
|
bundle = {name: np.load(bundle_dir / (name + ".npy"), mmap_mode="r", allow_pickle=False)
|
||||||
|
for name in ("input_matrix", "output_matrix", "kc_globals", "apl_globals")}
|
||||||
|
for name, shape in (("input_matrix", (2, 166700)), ("output_matrix", (2, 4064))):
|
||||||
|
value = bundle[name]
|
||||||
|
_check(value.dtype == np.dtype("float32") and value.shape == shape and value.flags.c_contiguous,
|
||||||
|
f"Frozen APL {name} shape/dtype/layout changed")
|
||||||
|
_check(np.isfinite(value).all() and np.all(value >= 0), f"Invalid positive raw-normalized APL {name}")
|
||||||
|
for name, count in (("kc_globals", 4064), ("apl_globals", 2)):
|
||||||
|
value = bundle[name]
|
||||||
|
_check(value.dtype == np.dtype("int32") and value.shape == (count,) and value[0] >= 0 and
|
||||||
|
value[-1] < 166700 and np.all(np.diff(value) > 0), f"Frozen APL identity {name} changed")
|
||||||
|
_check(not np.intersect1d(bundle["kc_globals"], bundle["apl_globals"]).size, "APL and KC identities overlap")
|
||||||
|
kc_positions = np.searchsorted(nodes, bundle["kc_globals"])
|
||||||
|
present = kc_positions < n
|
||||||
|
present[present] &= nodes[kc_positions[present]] == bundle["kc_globals"][present]
|
||||||
|
kc_local, kc_in_bundle = kc_positions[present], np.flatnonzero(present)
|
||||||
|
requested_globals, request_local, request_ptr, request_count = _requests(case_dir, nodes, steps)
|
||||||
|
initial = None
|
||||||
|
if (case_dir / "arrays.npz").exists():
|
||||||
|
with np.load(case_dir / "arrays.npz", allow_pickle=False) as archive:
|
||||||
|
_check(set(archive.files) == {"initial_v_mv", "initial_g_mv"}, "Unexpected initial-state schema")
|
||||||
|
initial = {name: archive[name].copy() for name in archive.files}
|
||||||
|
for name, value in initial.items():
|
||||||
|
_check(value.dtype == np.dtype("float64") and value.shape == (n,) and np.isfinite(value).all(),
|
||||||
|
f"Invalid diagnostic initial state: {name}")
|
||||||
|
history_bytes = steps * n * 40 if record_history else 0
|
||||||
|
_budget(budget_root, budget_limit, history_bytes + steps * (2 + 2 + 4064) * 4 + edges * 8 + (64 << 20))
|
||||||
|
versions = {name: importlib.metadata.version(name) for name in
|
||||||
|
("brian2", "numpy", "pandas", "pyarrow", "sympy", "scipy", "cython")}
|
||||||
|
_save(out_dir / "environment.json", {"python": sys.version, "platform": platform.platform(),
|
||||||
|
"packages": versions, "codegen": "numpy", "author_precision": "float64",
|
||||||
|
"APL_precision": "float32 in separate science-Python process", "Torch_imported_into_Brian": False})
|
||||||
|
for name, required in (("brian2", "2.5.1"), ("numpy", "1.22.3"), ("sympy", "1.12")):
|
||||||
|
_check(versions[name] == required, f"{name} must remain pinned to {required}")
|
||||||
|
import brian2 as b2
|
||||||
|
import pandas as pd
|
||||||
|
from brian2.core.base import BrianObject
|
||||||
|
|
||||||
|
ae = _load_checked(ae_path, AE_SHA256, "phase4ag_sealed_ae_helpers")
|
||||||
|
af = _load_checked(af_path, AF_SHA256, "phase4ag_sealed_af_helpers")
|
||||||
|
author = _load_checked(author_path, AUTHOR_SHA256, "phase4ag_unchanged_author")
|
||||||
|
_check("torch" not in sys.modules, "Torch must not be imported into the pinned Brian process")
|
||||||
|
comp = pd.read_csv(graph_dir / "completeness.csv", index_col=0)
|
||||||
|
_check(np.array_equal(comp.index.to_numpy(), nodes) and
|
||||||
|
np.array_equal(comp["local_index"].to_numpy(), np.arange(n)), "Author CSV neuron identity differs")
|
||||||
|
del comp
|
||||||
|
graph_hashes = {name: _digest(graph_dir / name) for name in
|
||||||
|
tuple(key + ".npy" for key in arrays) + ("completeness.csv", "connectivity.parquet")}
|
||||||
|
bundle_hashes = {name: _digest(bundle_dir / name) for name in BUNDLE_FILES}
|
||||||
|
case_hashes = {name: _digest(case_dir / name) for name in ("spec.json", "requests.npz")}
|
||||||
|
if initial is not None:
|
||||||
|
case_hashes["arrays.npz"] = _digest(case_dir / "arrays.npz")
|
||||||
|
worker_hash = _digest(worker_path)
|
||||||
|
coefficient_hash = _digest(coefficients_path)
|
||||||
|
baseline_coefficients = json.loads(coefficients_path.read_text(encoding="utf-8"))
|
||||||
|
if "legacy_apl_worker_sha256" in spec:
|
||||||
|
_check(worker_hash == spec["legacy_apl_worker_sha256"], "APL worker differs from preregistered source")
|
||||||
|
_save(out_dir / "input-audit.json", {"spec": spec, "case_hashes": case_hashes,
|
||||||
|
"graph_hashes": graph_hashes, "bundle_hashes": bundle_hashes,
|
||||||
|
"author_sha256": AUTHOR_SHA256, "ae_sha256": AE_SHA256, "af_sha256": AF_SHA256,
|
||||||
|
"legacy_apl_worker_sha256": worker_hash, "coefficients_sha256": coefficient_hash,
|
||||||
|
"candidate_trace_used_as_input": False,
|
||||||
|
"scope": "shared-APL-component closed-loop oracle, not all-components-independent CPU equivalence"})
|
||||||
|
saved_preferences = {key: b2.prefs[key] for key in
|
||||||
|
("codegen.target", "core.default_float_dtype", "legacy.refractory_timing")}
|
||||||
|
old_dt = b2.defaultclock.dt
|
||||||
|
b2.start_scope()
|
||||||
|
b2.prefs["codegen.target"] = "numpy"
|
||||||
|
b2.prefs["core.default_float_dtype"] = np.float64
|
||||||
|
b2.prefs["legacy.refractory_timing"] = False
|
||||||
|
b2.defaultclock.dt = .1 * b2.ms
|
||||||
|
parameters = dict(author.default_params)
|
||||||
|
_save(out_dir / "parameter-checks.json", ae._parameters_match(parameters, spec["model"], b2))
|
||||||
|
neu, syn, spikes = author.create_model(graph_dir / "completeness.csv", graph_dir / "connectivity.parquet", parameters)
|
||||||
|
_check(len(neu) == n and len(syn) == edges, "Author loaded an unexpected graph size")
|
||||||
|
_check(all(np.dtype(neu.variables[key].dtype) == np.float64 for key in ("v", "g")) and
|
||||||
|
np.dtype(syn.variables["w"].dtype) == np.float64, "Author states/weights are not float64")
|
||||||
|
effective = _new_memmap(out_dir / "weights.npy", "<f8", (edges,))
|
||||||
|
mapped_files.append(effective)
|
||||||
|
width, w_unit, mask_count = BLOCK_BYTES // 8, float(parameters["w_syn"] / b2.volt), 0
|
||||||
|
mask_hasher = hashlib.sha256()
|
||||||
|
base_hasher = hashlib.sha256()
|
||||||
|
effective_hasher = hashlib.sha256()
|
||||||
|
for begin in range(0, edges, width):
|
||||||
|
stop = min(edges, begin + width)
|
||||||
|
np.testing.assert_array_equal(np.asarray(syn.i[begin:stop]), arrays["src"][begin:stop])
|
||||||
|
np.testing.assert_array_equal(np.asarray(syn.j[begin:stop]), arrays["dst"][begin:stop])
|
||||||
|
original = np.asarray(syn.w_[begin:stop], dtype=np.float64).copy()
|
||||||
|
raw_expected = arrays["signed_raw"][begin:stop] * w_unit
|
||||||
|
_check(np.array_equal(original.view(np.uint64), raw_expected.view(np.uint64)) and
|
||||||
|
np.array_equal(original.view(np.uint64), arrays["weights"][begin:stop].view(np.uint64)),
|
||||||
|
"Actual original Brian weights differ from unchanged signed raw or AF base weights")
|
||||||
|
base_hasher.update(np.ascontiguousarray(original, dtype="<f8").tobytes())
|
||||||
|
mask = np.isin(nodes[arrays["src"][begin:stop]], bundle["apl_globals"])
|
||||||
|
mask_count += int(mask.sum())
|
||||||
|
mask_hasher.update(np.ascontiguousarray(arrays["edge_id"][begin:stop][mask], dtype="<i8").tobytes())
|
||||||
|
original[mask] = np.float64(0.0)
|
||||||
|
effective_hasher.update(np.ascontiguousarray(original, dtype="<f8").tobytes())
|
||||||
|
effective[begin:stop] = original
|
||||||
|
syn.w_[begin:stop] = original
|
||||||
|
if n == 166700:
|
||||||
|
_check(mask_count == 5845, "Full legacy APL fast-edge mask must contain exactly 5845 existing edges")
|
||||||
|
effective.flush()
|
||||||
|
_save(out_dir / "apl-mask-audit.json", {"count": mask_count, "ordered_original_edge_id_sha256": mask_hasher.hexdigest(),
|
||||||
|
"base_weight_raw_bytes_sha256": base_hasher.hexdigest(), "effective_weights_file_sha256": _digest(out_dir / "weights.npy"),
|
||||||
|
"effective_weights_raw_sha256": effective_hasher.hexdigest(),
|
||||||
|
"rule": "zero +0 all existing fast edges whose source GLOBAL neuron is in apl_globals; no graph edge removal",
|
||||||
|
"graded_targets": "only KC identities present in this LIF case", "KC_targets_in_case": len(kc_local),
|
||||||
|
"base_graph_files_modified": False, "fullgraph_required_mask_count": 5845})
|
||||||
|
if initial is not None:
|
||||||
|
neu.v = initial["initial_v_mv"] * b2.mV
|
||||||
|
neu.g = initial["initial_g_mv"] * b2.mV
|
||||||
|
v_raw = neu.variables["v"].get_value()
|
||||||
|
g_raw = neu.variables["g"].get_value()
|
||||||
|
last_raw = neu.variables["lastspike"].get_value()
|
||||||
|
available_raw = neu.variables["not_refractory"].get_value()
|
||||||
|
histories = {}
|
||||||
|
pre_apl_histories = {}
|
||||||
|
if record_history:
|
||||||
|
for name, dtype in (("v", "float64"), ("g", "float64"), ("ref", "int32")):
|
||||||
|
histories[name] = _new_memmap(out_dir / f"{name}-history.{dtype}.npy", np.dtype(dtype), (steps, n))
|
||||||
|
mapped_files.append(histories[name])
|
||||||
|
pre_apl_histories[name] = _new_memmap(out_dir / f"preAPL-{name}.{dtype}.npy", np.dtype(dtype), (steps, n))
|
||||||
|
mapped_files.append(pre_apl_histories[name])
|
||||||
|
apl_history = {}
|
||||||
|
for name, count in (("drive", 2), ("state", 2), ("inhibition", 4064)):
|
||||||
|
apl_history[name] = _new_memmap(out_dir / f"apl-{name}.float32.npy", "<f4", (steps, count))
|
||||||
|
mapped_files.append(apl_history[name])
|
||||||
|
_save(out_dir / "output-schema.json", {"history_recorded": record_history, "history_shape": [steps, n],
|
||||||
|
"state_hash_file": "tick-state-hashes.jsonl", "state_hash_encoding": "SHA256 of contiguous little-endian raw f64 V/g and i32 ref",
|
||||||
|
"APL_dtype": "float32", "APL_h_units": "mV; gain already applied in float32",
|
||||||
|
"APL_SI_conversion": "h.astype(float64) * float64(0.001), then separate float64 g subtraction",
|
||||||
|
"APL_write_schedule": "end, order=0, after original reset, unconditional raw g write; recorder end/order=1",
|
||||||
|
"APL_input": "Brian's own actual global spikes, never candidate spikes or candidate inhibition",
|
||||||
|
"APL_shapes": {"drive": [steps, 2], "state": [steps, 2], "inhibition": [steps, 4064]},
|
||||||
|
"request_columns": ["tick", "neuron_idx", "attempted", "accepted", "rejected"],
|
||||||
|
"queue_protocol": "sealed Phase4AF queue_summary; original global edge IDs, including zero-weight/ref-rejected arrivals",
|
||||||
|
"state_npz": ["step", "neuron_idx", "counts", "v", "g", "ref"],
|
||||||
|
"complete_marker": "summary.json complete=true only after worker exit and all checks"})
|
||||||
|
delay_steps = int(round(float(parameters["t_dly"] / b2.ms) / .1))
|
||||||
|
ref_steps = int(round(float(parameters["t_rfc"] / b2.ms) / .1))
|
||||||
|
_check(delay_steps == 18 and ref_steps == 22, "Author delay/refractory changed")
|
||||||
|
queue_len = delay_steps + 1
|
||||||
|
due_counts = np.zeros(queue_len, np.int64)
|
||||||
|
spike_ring = [np.empty(0, np.int32) for _ in range(queue_len)]
|
||||||
|
outdegree = np.diff(arrays["ptr"])
|
||||||
|
request_seen = np.zeros(steps, np.uint8)
|
||||||
|
apl_seen = np.zeros(steps, np.uint8)
|
||||||
|
applicable_count = np.zeros(steps, np.int32)
|
||||||
|
rejected_count = np.zeros(steps, np.int32)
|
||||||
|
spike_count = np.zeros(steps, np.int32)
|
||||||
|
total_counts = np.zeros(n, np.int32)
|
||||||
|
records = {"rows": [], "peek_calls": 0, "advance_calls": 0, "installations": []}
|
||||||
|
last_ticks = np.zeros(n, np.int64)
|
||||||
|
final_ref = np.zeros(n, np.int32)
|
||||||
|
permitted = np.empty(0, np.int32)
|
||||||
|
total_events = 0
|
||||||
|
|
||||||
|
def tick_now():
|
||||||
|
return int(round(float(neu.clock.t / b2.second) / .0001))
|
||||||
|
|
||||||
|
def current_ref(tick):
|
||||||
|
seen = np.isfinite(last_raw) & (last_raw >= 0)
|
||||||
|
last_ticks.fill(0)
|
||||||
|
last_ticks[seen] = np.rint(last_raw[seen] / .0001).astype(np.int64)
|
||||||
|
result = np.where(seen, np.maximum(ref_steps - (tick - last_ticks), 0), 0).astype(np.int32)
|
||||||
|
_check(np.array_equal(result == 0, available_raw), "Ref history disagrees with author not_refractory")
|
||||||
|
return result
|
||||||
|
|
||||||
|
with ExitStack() as stack:
|
||||||
|
stderr = stack.enter_context((out_dir / "apl-worker.stderr.log").open("xb"))
|
||||||
|
worker = _APLWorker(science_python, worker_path, bundle_dir, stderr, float(spec.get("worker_timeout_seconds", 180)))
|
||||||
|
_save(out_dir / "apl-worker-handshake.json", {"command": worker.command, "handshake": worker.hello})
|
||||||
|
queue_file = stack.enter_context((out_dir / "queue.jsonl").open("x", encoding="utf-8"))
|
||||||
|
event_file = stack.enter_context((out_dir / "events.bin").open("xb"))
|
||||||
|
hash_file = stack.enter_context((out_dir / "tick-state-hashes.jsonl").open("x", encoding="utf-8"))
|
||||||
|
tick_file = stack.enter_context((out_dir / "ticks.jsonl").open("x", encoding="utf-8"))
|
||||||
|
requests_file = stack.enter_context((out_dir / "requests.csv").open("x", encoding="utf-8", newline=""))
|
||||||
|
request_writer = csv.DictWriter(requests_file, fieldnames=["tick", "neuron_idx", "attempted", "accepted", "rejected"])
|
||||||
|
request_writer.writeheader()
|
||||||
|
|
||||||
|
def request_operation():
|
||||||
|
nonlocal permitted
|
||||||
|
tick = tick_now()
|
||||||
|
_check(0 <= tick < steps and not request_seen[tick], "Invalid/duplicate common request tick")
|
||||||
|
request_seen[tick] = 1
|
||||||
|
begin, stop = request_ptr[tick:tick + 2]
|
||||||
|
local = request_local[begin:stop]
|
||||||
|
available = available_raw[local].copy()
|
||||||
|
permitted = local[available]
|
||||||
|
applicable_count[tick] = len(permitted)
|
||||||
|
rejected_count[tick] = len(local) - len(permitted)
|
||||||
|
for node, accepted in zip(requested_globals[begin:stop], available):
|
||||||
|
request_writer.writerow({"tick": tick, "neuron_idx": int(node), "attempted": 1,
|
||||||
|
"accepted": int(accepted), "rejected": int(not accepted)})
|
||||||
|
if len(permitted):
|
||||||
|
neu.v[permitted] = parameters["v_th"] + 1 * b2.mV
|
||||||
|
|
||||||
|
def apl_operation():
|
||||||
|
tick = tick_now()
|
||||||
|
_check(0 <= tick < steps and not apl_seen[tick] and request_seen[tick], "Invalid/duplicate APL tick")
|
||||||
|
active = np.asarray(neu.spikes, dtype=np.int32)
|
||||||
|
_check(not len(active) or np.all(np.diff(active) > 0), "Brian actual spikes are not canonical/unique")
|
||||||
|
_check(np.all(g_raw[active] == 0.0), "APL ran before the original author g reset")
|
||||||
|
if record_history:
|
||||||
|
pre_apl_histories["v"][tick] = v_raw
|
||||||
|
pre_apl_histories["g"][tick] = g_raw
|
||||||
|
pre_apl_histories["ref"][tick] = current_ref(tick)
|
||||||
|
drive, state, inhibition = worker.step(tick, np.asarray(nodes[active], dtype=np.int32))
|
||||||
|
apl_history["drive"][tick] = drive
|
||||||
|
apl_history["state"][tick] = state
|
||||||
|
apl_history["inhibition"][tick] = inhibition
|
||||||
|
# These are separate array operations. Do not move the unit
|
||||||
|
# conversion into a fused subtract; do not guard by refractory.
|
||||||
|
delta_si = inhibition[kc_in_bundle].astype(np.float64) * np.float64(.001)
|
||||||
|
g_raw[kc_local] = g_raw[kc_local] - delta_si
|
||||||
|
apl_seen[tick] = 1
|
||||||
|
|
||||||
|
def record_end():
|
||||||
|
nonlocal last_complete_tick, total_events, final_ref
|
||||||
|
tick = tick_now()
|
||||||
|
_check(tick == last_complete_tick + 1 and tick < steps and apl_seen[tick], "End tick is incomplete/out of order")
|
||||||
|
_check(len(records["rows"]) == tick + 1, "End state lacks queue observation")
|
||||||
|
_check(np.isfinite(v_raw).all() and np.isfinite(g_raw).all(), "Nonfinite author/APL state")
|
||||||
|
final_ref = current_ref(tick)
|
||||||
|
if record_history:
|
||||||
|
histories["v"][tick], histories["g"][tick], histories["ref"][tick] = v_raw, g_raw, final_ref
|
||||||
|
active = np.asarray(neu.spikes, dtype=np.int32)
|
||||||
|
_check(np.isin(permitted, active).all(), "An applicable request did not produce a real spike")
|
||||||
|
spike_count[tick] = len(active)
|
||||||
|
total_counts[active] += 1
|
||||||
|
if len(active):
|
||||||
|
events = np.empty(len(active), EVENT_DTYPE)
|
||||||
|
events["step"], events["neuron_idx"] = tick, nodes[active]
|
||||||
|
event_file.write(memoryview(events).cast("B"))
|
||||||
|
total_events += len(active)
|
||||||
|
spike_ring[tick % queue_len] = active.copy()
|
||||||
|
due_counts[(tick + delay_steps) % queue_len] = int(outdegree[active].sum(dtype=np.int64))
|
||||||
|
hash_file.write(json.dumps({"tick": tick, "v_sha256": _array_hash(v_raw, "<f8"),
|
||||||
|
"g_sha256": _array_hash(g_raw, "<f8"), "ref_sha256": _array_hash(final_ref, "<i4")}, sort_keys=True) + "\n")
|
||||||
|
tick_file.write(json.dumps({"tick": tick, "spikes": len(active), "requests": int(request_count[tick]),
|
||||||
|
"applicable_requests": int(applicable_count[tick]), "ref_rejected_requests": int(rejected_count[tick]),
|
||||||
|
"event_sha256": _array_hash(nodes[active], "<i4"),
|
||||||
|
"due_arrivals": records["rows"][tick]["count"], "accepted_arrivals": records["rows"][tick]["accepted_count"],
|
||||||
|
"APL_drive_sha256": _array_hash(apl_history["drive"][tick], "<f4"),
|
||||||
|
"APL_state_sha256": _array_hash(apl_history["state"][tick], "<f4"),
|
||||||
|
"APL_inhibition_sha256": _array_hash(apl_history["inhibition"][tick], "<f4")}, sort_keys=True) + "\n")
|
||||||
|
_budget(budget_root, budget_limit, reserve=1 << 20)
|
||||||
|
last_complete_tick = tick
|
||||||
|
if (tick + 1) % 100 == 0 or tick + 1 == steps:
|
||||||
|
for mapped in mapped_files:
|
||||||
|
mapped.flush()
|
||||||
|
for handle in (queue_file, event_file, hash_file, tick_file, requests_file):
|
||||||
|
handle.flush()
|
||||||
|
print(json.dumps({"oracle": spec["name"], "completed_ticks": tick + 1,
|
||||||
|
"spikes": total_events, "APL_worker_ticks": worker.tick}), flush=True)
|
||||||
|
|
||||||
|
class QueueInstaller(BrianObject):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(clock=neu.clock, when="end", order=1_000_000, name="zz_apl_queue_installer")
|
||||||
|
|
||||||
|
def before_run(self, run_namespace):
|
||||||
|
installed = []
|
||||||
|
for code in syn.pre.code_objects:
|
||||||
|
if "_queue" not in code.namespace or "_queue.peek()" not in str(code.code):
|
||||||
|
continue
|
||||||
|
original = code.namespace["_queue"]
|
||||||
|
if isinstance(original, _QueueProxy):
|
||||||
|
original = original._original_queue
|
||||||
|
code.namespace["_queue"] = _QueueProxy(original, tick_now, available_raw, arrays, identity_edges,
|
||||||
|
due_counts, spike_ring, delay_steps, queue_file, records, af.queue_summary)
|
||||||
|
installed.append(code.name)
|
||||||
|
_check(len(installed) == 1, "Expected one original anatomical queue consumer")
|
||||||
|
records["installations"].append(installed[0])
|
||||||
|
|
||||||
|
objects = [neu, syn, spikes,
|
||||||
|
b2.NetworkOperation(request_operation, clock=neu.clock, when="before_thresholds", order=0, name="oracle_common_requests"),
|
||||||
|
b2.NetworkOperation(apl_operation, clock=neu.clock, when="end", order=0, name="oracle_legacy_apl_unconditional"),
|
||||||
|
b2.NetworkOperation(record_end, clock=neu.clock, when="end", order=1, name="oracle_after_apl_record"), QueueInstaller()]
|
||||||
|
network = b2.Network(*objects)
|
||||||
|
_save(out_dir / "schedule.json", {"schedule": list(network.schedule), "summary": str(network.scheduling_summary())})
|
||||||
|
network.run(0 * b2.ms, namespace={})
|
||||||
|
_save(out_dir / "compiled-code.json", ae._code_records(network))
|
||||||
|
compiled_coefficients = ae._coefficients(neu, parameters, b2, .0001)
|
||||||
|
coefficient_keys = ("gd", "c0", "cg", "cv", "threshold", "reset", "seed_volt")
|
||||||
|
_check(all(float(compiled_coefficients[key]).hex() == float(baseline_coefficients[key]).hex()
|
||||||
|
for key in coefficient_keys), "Compiled Brian coefficients differ from sealed AF")
|
||||||
|
_check(last_complete_tick == -1 and worker.tick == 0 and not records["rows"] and not request_seen.any(),
|
||||||
|
"Zero-duration compilation unexpectedly advanced state")
|
||||||
|
network.run(steps * .1 * b2.ms, namespace={})
|
||||||
|
_save(out_dir / "generated-code.json", ae._code_records(network))
|
||||||
|
worker_status = worker.finish(steps)
|
||||||
|
worker = None
|
||||||
|
|
||||||
|
_check(last_complete_tick == steps - 1 and np.all(request_seen == 1) and np.all(apl_seen == 1), "Incomplete trial")
|
||||||
|
_check(records["peek_calls"] == records["advance_calls"] == steps, "Incomplete queue audit")
|
||||||
|
_check(total_events == int(spikes.num_spikes) and np.array_equal(total_counts, np.asarray(spikes.count[:])),
|
||||||
|
"Sparse events disagree with original SpikeMonitor")
|
||||||
|
_check(np.array_equal(request_count, applicable_count + rejected_count), "Incomplete request accounting")
|
||||||
|
_check(np.all(np.asarray(neu.rfc[:] / b2.ms) == float(parameters["t_rfc"] / b2.ms)), "Author refractory duration changed")
|
||||||
|
for begin in range(0, edges, width):
|
||||||
|
stop = min(edges, begin + width)
|
||||||
|
_check(np.array_equal(np.asarray(syn.w_[begin:stop]).view(np.uint64), effective[begin:stop].view(np.uint64)),
|
||||||
|
"Effective synaptic weights changed during the trial")
|
||||||
|
event_values = np.memmap(out_dir / "events.bin", dtype=EVENT_DTYPE, mode="r", shape=(total_events,)) if total_events else np.empty(0, EVENT_DTYPE)
|
||||||
|
_check((out_dir / "events.bin").stat().st_size == total_events * 8, "Sparse event byte count mismatch")
|
||||||
|
for begin in range(0, total_events, width):
|
||||||
|
stop = min(total_events, begin + width)
|
||||||
|
spike_local = np.asarray(spikes.i[begin:stop], dtype=np.int32)
|
||||||
|
np.testing.assert_array_equal(event_values["neuron_idx"][begin:stop], nodes[spike_local])
|
||||||
|
times = np.rint(np.asarray(spikes.t[begin:stop] / b2.second) / .0001).astype(np.int32)
|
||||||
|
np.testing.assert_array_equal(event_values["step"][begin:stop], times)
|
||||||
|
_budget(budget_root, budget_limit, total_events * 8 + n * 24 + (8 << 20))
|
||||||
|
with (out_dir / "state.npz").open("xb") as handle:
|
||||||
|
np.savez_compressed(handle, step=event_values["step"], neuron_idx=event_values["neuron_idx"],
|
||||||
|
counts=total_counts, v=v_raw, g=g_raw, ref=final_ref)
|
||||||
|
with (out_dir / "tick-summary.npz").open("xb") as handle:
|
||||||
|
np.savez_compressed(handle, request_count=request_count, applicable_count=applicable_count,
|
||||||
|
rejected_count=rejected_count, spike_count=spike_count,
|
||||||
|
arrival_count=np.asarray([row["count"] for row in records["rows"]], np.int64),
|
||||||
|
accepted_arrival_count=np.asarray([row["accepted_count"] for row in records["rows"]], np.int64))
|
||||||
|
coefficients = ae._coefficients(neu, parameters, b2, .0001)
|
||||||
|
keys = ("gd", "c0", "cg", "cv", "threshold", "reset", "seed_volt")
|
||||||
|
_check(all(float(coefficients[key]).hex() == float(baseline_coefficients[key]).hex() for key in keys),
|
||||||
|
"Actual Brian coefficients differ from sealed AF coefficients")
|
||||||
|
_save(out_dir / "coefficients.json", coefficients)
|
||||||
|
_save(out_dir / "queue-audit.json", {"peek_calls": records["peek_calls"], "advance_calls": records["advance_calls"],
|
||||||
|
"installations": records["installations"], "same_peek_object_returned": True,
|
||||||
|
"original_edge_ids_not_sorted_or_filtered": True, "zero_weight_and_refractory_rejected_edges_retained": True,
|
||||||
|
"post_threshold_pre_synaptic_guard_observed": True, "forwarding_contract": "sealed AE/AF design",
|
||||||
|
"new_unwrapped_repeat_performed": False, "limit": "Current wrapper was not independently rerun without the queue proxy"})
|
||||||
|
for path, expected in ((author_path, AUTHOR_SHA256), (ae_path, AE_SHA256), (af_path, AF_SHA256), (worker_path, worker_hash)):
|
||||||
|
_check(_digest(path) == expected, f"Source changed during the run: {path}")
|
||||||
|
_check(_digest(coefficients_path) == coefficient_hash, "Sealed coefficient reference changed during the run")
|
||||||
|
for directory, hashes in ((graph_dir, graph_hashes), (bundle_dir, bundle_hashes), (case_dir, case_hashes)):
|
||||||
|
for name, expected in hashes.items():
|
||||||
|
_check(_digest(directory / name) == expected, f"Read-only input changed during the run: {name}")
|
||||||
|
for mapped in mapped_files:
|
||||||
|
mapped.flush()
|
||||||
|
_check("torch" not in sys.modules, "Pinned Brian process unexpectedly imported Torch")
|
||||||
|
output_bytes = _budget(budget_root, budget_limit, 1 << 20)
|
||||||
|
summary = {"name": spec["name"], "complete": True, "precision": "float64", "APL_precision": "float32",
|
||||||
|
"backend": "shared-APL-component closed-loop Brian2 oracle", "steps": steps, "completed_ticks": last_complete_tick + 1,
|
||||||
|
"nodes": n, "edges": edges, "spikes": total_events, "requests": int(request_count.sum()),
|
||||||
|
"applicable_requests": int(applicable_count.sum()), "ref_rejected_requests": int(rejected_count.sum()),
|
||||||
|
"APL_fast_edges_zeroed": mask_count, "APL_worker_exit_status": worker_status, "APL_worker_ticks": steps,
|
||||||
|
"apl_fast_edges_zeroed": mask_count, "effective_weights_raw_sha256": effective_hasher.hexdigest(),
|
||||||
|
"kc_targets_present": len(kc_local),
|
||||||
|
"candidate_trace_used_as_input": False, "independent_CPU_all_components_claim": False,
|
||||||
|
"history_recorded": record_history, "single_continuous_run": True, "no_training": True, "no_poi": True,
|
||||||
|
"source_and_inputs_unchanged": True, "pass_all": True,
|
||||||
|
"pass_all_scope": "Oracle construction, protocol and internal self-checks only; candidate comparison is a separate gate",
|
||||||
|
"scope": "Only this fixed trajectory; legacy Torch APL is a shared numerical component, not an independent CPU APL implementation",
|
||||||
|
"output_budget_bytes": budget_limit, "output_bytes_before_summary": output_bytes,
|
||||||
|
"state_hashes_sha256": _digest(out_dir / "tick-state-hashes.jsonl"), "queue_sha256": _digest(out_dir / "queue.jsonl"),
|
||||||
|
"events_sha256": _digest(out_dir / "events.bin"), "weights_sha256": _digest(out_dir / "weights.npy")}
|
||||||
|
_save(out_dir / "summary.json", summary)
|
||||||
|
return summary
|
||||||
|
except Exception as error:
|
||||||
|
for mapped in mapped_files:
|
||||||
|
mapped.flush()
|
||||||
|
_save(out_dir / "error.json", {"complete": False, "last_complete_tick": last_complete_tick,
|
||||||
|
"type": type(error).__name__, "message": str(error), "partial_files_preserved": True,
|
||||||
|
"inputs_or_duration_adjusted": False})
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
if worker is not None:
|
||||||
|
worker.abort()
|
||||||
|
if saved_preferences is not None:
|
||||||
|
for key, value in saved_preferences.items():
|
||||||
|
b2.prefs[key] = value
|
||||||
|
b2.defaultclock.dt = old_dt
|
||||||
|
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
"""Preregister exact legacy APL data and unmodified fixed CAL requests."""
|
||||||
|
from datetime import datetime,timezone
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import yaml
|
||||||
|
from context import ROOT,MODEL,EXP,AF_MODEL,AF_EXP,AD_EXP,CFG,save,digest,sources,integrity,budget
|
||||||
|
|
||||||
|
def arr(path,value):
|
||||||
|
with Path(path).open('xb') as f:np.save(f,value,allow_pickle=False)
|
||||||
|
|
||||||
|
def graph(folder,nodes,full):
|
||||||
|
folder.mkdir();nodes=np.asarray(nodes,np.int32);ptr,dst,src,raw,base=full
|
||||||
|
if len(nodes)==CFG['neurons']:ids=np.arange(len(dst),dtype=np.int64)
|
||||||
|
else:
|
||||||
|
ids=np.concatenate([np.arange(ptr[s],ptr[s+1],dtype=np.int64) for s in nodes])
|
||||||
|
ids=ids[np.isin(dst[ids],nodes)]
|
||||||
|
lookup=np.full(CFG['neurons'],-1,np.int32);lookup[nodes]=np.arange(len(nodes),dtype=np.int32)
|
||||||
|
ss,dd=lookup[src[ids]],lookup[dst[ids]];pp=np.r_[np.int64(0),np.bincount(ss,minlength=len(nodes)).cumsum(dtype=np.int64)]
|
||||||
|
for name,value in dict(nodes=nodes,edge_id=ids,src=ss,dst=dd,ptr=pp,signed_raw=raw[ids],weights=base[ids]).items():arr(folder/(name+'.npy'),value)
|
||||||
|
pd.DataFrame({'local_index':np.arange(len(nodes),dtype=np.int32)},index=pd.Index(nodes,name='global_neuron_idx')).to_csv(folder/'completeness.csv')
|
||||||
|
pd.DataFrame({'Presynaptic_Index':ss,'Postsynaptic_Index':dd,'Excitatory x Connectivity':raw[ids],'edge_id':ids},copy=False).to_parquet(folder/'connectivity.parquet',index=False)
|
||||||
|
save(folder/'audit.json',dict(nodes=len(nodes),edges=len(ids),canonical_original_edge_ids=True,anatomical_weights_not_modified=True,
|
||||||
|
effective_APL_zeroing='Only in new runtime clone, never these original weight files'))
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
def case(name,kind,steps,nodes,graphdir,requests,initial=None,extra=None):
|
||||||
|
folder=EXP/'cases'/name;folder.mkdir()
|
||||||
|
model=json.loads((AD_EXP/'protocol/preregistered.json').read_text())['config']['model']
|
||||||
|
spec=dict(name=name,kind=kind,steps=steps,dt_ms=.1,duration_ms=steps*.1,model=model,
|
||||||
|
graph_dir=str(graphdir),apl_bundle_dir=str(EXP/'apl-bundle'),apl=CFG['apl'],record_history=kind=='fixture',
|
||||||
|
coefficients_path=str(AF_EXP/'oracle/no_input/coefficients.json'),
|
||||||
|
science_python=str(ROOT/'models/male-cns-lif/.venv/bin/python'),legacy_apl_worker=str(MODEL/'legacy_apl_worker.py'),
|
||||||
|
budget_root=str(EXP),output_budget_bytes=CFG['output_budget_bytes'],precision='float64',apl_precision='float32',training=False)
|
||||||
|
if extra:spec.update(extra)
|
||||||
|
requests=np.asarray(requests,dtype=np.int32).reshape(-1,2)
|
||||||
|
if len(requests):
|
||||||
|
requests=requests[np.lexsort((requests[:,1],requests[:,0]))]
|
||||||
|
assert len(np.unique(requests.astype(np.int64)[:,0]*CFG['neurons']+requests[:,1]))==len(requests)
|
||||||
|
assert requests[:,0].min()>=0 and requests[:,0].max()<steps and np.isin(requests[:,1],nodes).all()
|
||||||
|
with (folder/'requests.npz').open('xb') as f:np.savez_compressed(f,tick=requests[:,0],neuron_idx=requests[:,1])
|
||||||
|
if kind=='fixture':
|
||||||
|
v=np.full(len(nodes),model['resting_potential_mv'],np.float64);g=np.zeros(len(nodes),np.float64)
|
||||||
|
if initial:
|
||||||
|
for node,value in initial.get('v',{}).items():v[np.flatnonzero(nodes==node)[0]]=value
|
||||||
|
for node,value in initial.get('g',{}).items():g[np.flatnonzero(nodes==node)[0]]=value
|
||||||
|
with (folder/'arrays.npz').open('xb') as f:np.savez_compressed(f,initial_v_mv=v,initial_g_mv=g)
|
||||||
|
save(folder/'spec.json',spec)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
assert not (EXP/'protocol/preregistered.json').exists()
|
||||||
|
assert all(not (EXP/d).exists() or not any((EXP/d).iterdir()) for d in ('protocol','graphs','apl-bundle','cases','gpu','oracle'))
|
||||||
|
assert shutil.disk_usage(EXP.parent).free>30*1024**3
|
||||||
|
for d in ('protocol','apl-bundle','graphs','cases','gpu','oracle','component-audit','regression','calibration','audit','extension-build','logs'):(EXP/d).mkdir(parents=True,exist_ok=True)
|
||||||
|
can=ROOT/'datasets/male-cns-v1.0/processed/neuron-only';legacy=ROOT/'models/male-cns-lif';lp=legacy/'olfactory-grounding-v1/phase4l.yaml'
|
||||||
|
lock=ROOT/'experiments/phase4j-mb-physiology-repair/calibration/locked-parameters.json'
|
||||||
|
files=[AF_MODEL/'manifest.json',AF_EXP/'manifest.json',AF_EXP/'oracle/no_input/coefficients.json',
|
||||||
|
legacy/'deterministic-runtime-v2/phase4p_revalidate.py',lp,lock,can/'neuron-index/unified-metadata.parquet',can/'gpu/csr-weights.int64.npy',
|
||||||
|
legacy/'author-runtime-lab-v1/author_ext.cpp',legacy/'author-runtime-lab-v1/author_ext.cu',legacy/'author-runtime-lab-v1/gpu_backend.py',
|
||||||
|
legacy/'author-runtime-lab-v1/oracle_stress.py',AD_EXP/'external-resources/model.py',AF_MODEL/'oracle_full.py']
|
||||||
|
lroot=ROOT/'experiments/phase4l-olfactory-grounding'
|
||||||
|
files += [lroot/'odor-encoder'/x for x in ('frozen-odor-panel.parquet','mapped-glomerular-vectors.npz','selection.json')]
|
||||||
|
files += [lroot/'receptor-mapping/olfactory-mapping.parquet']
|
||||||
|
save(EXP/'protocol/preregistered.json',dict(timestamp_utc=datetime.now(timezone.utc).isoformat(),sources=sources(),config=CFG,
|
||||||
|
inputs=[dict(path=str(p.relative_to(ROOT)),sha256=digest(p)) for p in files],before_any_trajectory=True,
|
||||||
|
parent_commit=subprocess.check_output(['git','-C',str(ROOT),'rev-parse','HEAD'],text=True).strip()))
|
||||||
|
save(EXP/'regression/old-integrity-before.json',integrity())
|
||||||
|
locked=json.loads(lock.read_text());assert locked['parameters_locked'] and locked['calibration_only']
|
||||||
|
assert {k:locked['selected'][k] for k in ('gain','normalization','tau_ms')}==CFG['apl']
|
||||||
|
meta=pd.read_parquet(can/'neuron-index/unified-metadata.parquet').sort_values('neuron_idx').reset_index(drop=True)
|
||||||
|
assert len(meta)==CFG['neurons'] and np.array_equal(meta.neuron_idx,np.arange(CFG['neurons']))
|
||||||
|
cls=meta.annotation_class.fillna('').astype(str).to_numpy();typ=meta.annotation_type.fillna('').astype(str).to_numpy()
|
||||||
|
kc=np.flatnonzero(cls=='Kenyon_Cell').astype(np.int32);pn=np.flatnonzero(cls=='ALPN').astype(np.int32);apl=np.flatnonzero(typ=='APL').astype(np.int32)
|
||||||
|
assert len(kc)==4064 and len(apl)==2
|
||||||
|
fg=AF_EXP/'graph';ptr=np.load(fg/'ptr.npy',mmap_mode='r');dst=np.load(fg/'dst.npy',mmap_mode='r');src=np.load(fg/'src.npy',mmap_mode='r')
|
||||||
|
signed=np.load(fg/'signed_raw.npy',mmap_mode='r');base=np.load(AF_EXP/'oracle/no_input/weights.npy',mmap_mode='r');raw=np.load(can/'gpu/csr-weights.int64.npy',mmap_mode='r')
|
||||||
|
assert len(dst)==CFG['edges'] and int(raw.sum())==CFG['raw_weight_sum']
|
||||||
|
aplout=np.isin(src,apl);aplids=np.flatnonzero(aplout).astype(np.int64);assert len(aplids)==5845
|
||||||
|
I=np.zeros((2,len(meta)),np.float32);O=np.zeros((2,len(kc)),np.float32)
|
||||||
|
alook={int(v):i for i,v in enumerate(apl)};kl=np.full(len(meta),-1,np.int32);kl[kc]=np.arange(len(kc),dtype=np.int32)
|
||||||
|
allowed=np.isin(src,np.r_[kc,pn])&np.isin(dst,apl)
|
||||||
|
for eid in np.flatnonzero(allowed):I[alook[int(dst[eid])],int(src[eid])]+=float(raw[eid])
|
||||||
|
for eid in np.flatnonzero(aplout&np.isin(dst,kc)):O[alook[int(src[eid])],kl[dst[eid]]]+=float(raw[eid])
|
||||||
|
iscale=float(I[I>0].sum()/np.count_nonzero(np.any(I>0,axis=0)));oscale=float(O[O>0].mean());bundle=EXP/'apl-bundle'
|
||||||
|
for name,value in dict(input_matrix=I/iscale,output_matrix=O/oscale,input_raw=I,output_raw=O,kc_globals=kc,pn_globals=pn,apl_globals=apl,apl_out_ids=aplids).items():arr(bundle/(name+'.npy'),value)
|
||||||
|
save(bundle/'scales.json',dict(input_scale=iscale,output_scale=oscale))
|
||||||
|
save(bundle/'provenance.json',dict(canonical_root=str(can),source=str(legacy/'deterministic-runtime-v2/phase4p_revalidate.py'),source_sha256=digest(legacy/'deterministic-runtime-v2/phase4p_revalidate.py'),
|
||||||
|
parameters=CFG['apl'],lock_file=str(lock),lock_sha256=digest(lock),full_dimensions=[list(I.shape),list(O.shape)],
|
||||||
|
APL=len(apl),KC=len(kc),ALPN=len(pn),APL_fast_edges=len(aplids),APL_nonKC_edges=int(np.count_nonzero(aplout&~np.isin(dst,kc))),
|
||||||
|
APL_nonKC_contacts=int(raw[aplout&~np.isin(dst,kc)].sum()),normalization_recomputed_in_original_order=True,
|
||||||
|
raw_files_modified=False))
|
||||||
|
full=(ptr,dst,src,signed,base);fullnodes=graph(EXP/'graphs/full',np.arange(len(meta),dtype=np.int32),full)
|
||||||
|
pscore=I.sum(axis=0);pnrank=pn[np.lexsort((pn,-pscore[pn]))];kscore=O.sum(axis=0);kcrank=kc[np.lexsort((kc,-kscore))]
|
||||||
|
candidates=np.flatnonzero(np.isin(src,pn)&np.isin(dst,kc));best=int(candidates[np.argmax(raw[candidates])]);pairpn=int(src[best])
|
||||||
|
pe=np.arange(ptr[pairpn],ptr[pairpn+1],dtype=np.int64);pe=pe[np.isin(dst[pe],kc)];pe=pe[np.lexsort((dst[pe],-raw[pe]))]
|
||||||
|
collision_kc=np.unique(dst[pe[:3]]);assert len(collision_kc)==3
|
||||||
|
nonkc=aplids[~np.isin(dst[aplids],kc)];nonkc_target=int(dst[nonkc[np.argmax(raw[nonkc])]])
|
||||||
|
nodes=np.unique(np.r_[apl,pnrank[:16],kcrank[:16],pairpn,collision_kc,nonkc_target,[1197,1381,1511,82312,133666]]).astype(np.int32)
|
||||||
|
fixturegraph=EXP/'graphs/fixtures';graph(fixturegraph,nodes,full)
|
||||||
|
p=int(pnrank[0]);k=int(kcrank[0]);kc1,kc2,kc3=map(int,collision_kc)
|
||||||
|
designs=[('zero',100,[],None),('pn_pulse',300,[(0,p)],None),
|
||||||
|
('kc_ref_boundary',100,[(t,k) for t in (0,1,21,22,23,44)],None),
|
||||||
|
('two_sources',300,[(t,n) for t in (0,22,44,66,88) for n in (p,k)],None),
|
||||||
|
('arrival_collision',120,[(0,pairpn),(0,kc1),(18,kc2),(21,kc1)],None),
|
||||||
|
('natural_request',100,[(0,k)],dict(v={k:-44.0})),
|
||||||
|
('apl_only',100,[(0,int(a)) for a in apl],None),
|
||||||
|
('high_fanin',400,[(t,int(n)) for t in (0,22,44) for n in nodes if pscore[n]>0],dict(g={k:.123}))]
|
||||||
|
assert [v[0] for v in designs]==CFG['fixtures']
|
||||||
|
for name,steps,requests,initial in designs:case(name,'fixture',steps,nodes,fixturegraph,requests,initial)
|
||||||
|
meta.iloc[nodes][['neuron_idx','body_id','annotation_class','annotation_type','neurotransmitter']].to_csv(EXP/'protocol/fixture-identities.csv',index=False)
|
||||||
|
save(EXP/'protocol/fixture-selection.json',dict(pn=p,kc=k,pair_PN=pairpn,arrival_KCs=collision_kc.tolist(),real_PN_KC_edge=best,
|
||||||
|
nonKC_APL_target=nonkc_target,method='Static raw-count ranks and exact metadata; retain ALL existing induced edges and full APL matrices/norms',runtime_selection=False))
|
||||||
|
os.environ['CUDA_VISIBLE_DEVICES']=CFG['gpu_uuid'];sys.path.insert(0,str(legacy));sys.path.insert(0,str(legacy/'deterministic-runtime-v2'))
|
||||||
|
sys.path.insert(0,str(legacy/'terminal-scope-diagnostic-v1'));from diagnostic import queues
|
||||||
|
queues()
|
||||||
|
import torch
|
||||||
|
from phase4p_revalidate import door_inputs,make_drive
|
||||||
|
oc,panel,vectors,selection,mapping=door_inputs();cal=panel[panel.split=='calibration'].copy();assert len(panel)==12 and len(cal)==6
|
||||||
|
assert oc['odor_encoder']['evaluation_seeds']==CFG['calibration']['seeds']
|
||||||
|
assert float(oc['odor_encoder']['duration_ms'])==CFG['calibration']['duration_ms']
|
||||||
|
cal.to_parquet(EXP/'protocol/calibration-panel.parquet',index=False);calrecords=[]
|
||||||
|
for mode in CFG['calibration']['modes']:
|
||||||
|
for oi,(_,odor) in enumerate(cal.iterrows()):
|
||||||
|
targets,rates=make_drive(oc,panel,vectors,selection,mapping,odor.odor_id,mode)
|
||||||
|
assert len(np.unique(targets))==len(targets),'Original encoder emits duplicate PN targets; audit instead of silently merging'
|
||||||
|
rates=np.asarray(rates,np.float32);steps=round(CFG['calibration']['duration_ms']/.1)
|
||||||
|
for seed in CFG['calibration']['seeds']:
|
||||||
|
gen=torch.Generator(device='cuda');gen.manual_seed(seed)
|
||||||
|
original_probability=rates*.1/1000.0
|
||||||
|
explicit_probability=rates*np.float32(.1)/np.float32(1000.)
|
||||||
|
assert original_probability.dtype==np.float32 and np.array_equal(original_probability.view(np.uint32),explicit_probability.view(np.uint32))
|
||||||
|
probs=torch.as_tensor(original_probability,dtype=torch.float32,device='cuda')
|
||||||
|
forced=(torch.rand((steps,len(targets)),generator=gen,device='cuda')<probs[None,:]).cpu().numpy()
|
||||||
|
tt,cc=np.nonzero(forced);req=np.column_stack([tt,targets[cc]]).astype(np.int32)
|
||||||
|
name=f'cal-{mode}-{oi:02d}-s{seed}'
|
||||||
|
case(name,'calibration',steps,fullnodes,EXP/'graphs/full',req,extra=dict(odor_id=str(odor.odor_id),odor_name=str(odor.odor_name),
|
||||||
|
mode=mode,seed=seed,odor_index=oi,expected_external_events=float(rates.sum())*steps*.1/1000.,target_count=len(targets),rate_sum_hz=float(rates.sum())))
|
||||||
|
with (EXP/'cases'/name/'pn-drive.npz').open('xb') as f:np.savez_compressed(f,targets=targets,rates_hz=rates)
|
||||||
|
calrecords.append(dict(name=name,mode=mode,odor_index=oi,odor_id=str(odor.odor_id),seed=seed,requests=len(req),rates_sum=float(rates.sum())))
|
||||||
|
save(EXP/'protocol/calibration-cases.json',calrecords)
|
||||||
|
save(EXP/'protocol/encoder-audit.json',dict(panel_count=12,cal_count=6,median_mapped_response_sum=float(np.median(panel.mapped_response_sum)),
|
||||||
|
target_rng_column_order='Original pn_drive, no sorting before torch.rand',seeds=CFG['calibration']['seeds'],
|
||||||
|
requested_before_any_dynamics=True,formal_AB_run=False,heldout_run=False,torch=torch.__version__,numpy=np.__version__,
|
||||||
|
generation='Original rates*.1/1000 float32 GPU Bernoulli, independent per-case original seed'))
|
||||||
|
save(EXP/'protocol/prepared-hashes.json',[dict(path=str(p.relative_to(EXP)),bytes=p.stat().st_size,sha256=digest(p))
|
||||||
|
for d in ('graphs','apl-bundle','cases','protocol') for p in sorted((EXP/d).rglob('*')) if p.is_file() and p.name!='prepared-hashes.json'])
|
||||||
|
budget();print('PREPARED8 fixtures and60 fixed CAL inputs; no trajectories; frozen integrity PASS',flush=True)
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
"""A fresh process per declared case; no concurrent scientific GPU jobs."""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
from context import ROOT,MODEL,EXP,CFG,check,budget
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser=argparse.ArgumentParser()
|
||||||
|
parser.add_argument('backend',choices=['gpu','oracle','component'])
|
||||||
|
parser.add_argument('case')
|
||||||
|
parser.add_argument('--repeat',type=int,default=0)
|
||||||
|
args=parser.parse_args()
|
||||||
|
assert '/' not in args.case and '..' not in args.case and 0<=args.repeat<3
|
||||||
|
check();budget()
|
||||||
|
os.environ['CUDA_VISIBLE_DEVICES']=CFG['gpu_uuid']
|
||||||
|
os.environ['CUDA_HOME']='/usr/local/cuda'
|
||||||
|
os.environ['PATH']=str(ROOT/'models/male-cns-lif/.venv/bin')+':/usr/local/cuda/bin:'+os.environ['PATH']
|
||||||
|
os.environ['MAX_JOBS']='2';os.environ['TORCH_CUDA_ARCH_LIST']='8.9'
|
||||||
|
# The pinned Brian environment intentionally has neither Torch nor PyYAML.
|
||||||
|
# Keep this preflight standard-library-only; never install into that env.
|
||||||
|
for port in (8188,8189,8190):
|
||||||
|
with urllib.request.urlopen(f'http://192.168.10.51:{port}/queue',timeout=5) as response:
|
||||||
|
queue=json.load(response)
|
||||||
|
assert not queue['queue_running'] and not queue['queue_pending'],'ComfyUI busy: defer, never evict'
|
||||||
|
case=EXP/'cases'/args.case
|
||||||
|
assert case.is_dir()
|
||||||
|
out=EXP/'gpu'/f'{args.case}-r{args.repeat}'
|
||||||
|
if args.backend=='gpu':
|
||||||
|
from gpu_apl import run_gpu
|
||||||
|
result=run_gpu(case,out,EXP/'extension-build')
|
||||||
|
elif args.backend=='oracle':
|
||||||
|
assert args.repeat==0
|
||||||
|
from oracle_apl import run_case
|
||||||
|
result=run_case(case,EXP/'oracle'/args.case)
|
||||||
|
else:
|
||||||
|
assert args.repeat==0
|
||||||
|
from validate_components import validate
|
||||||
|
result=validate(out,EXP/'apl-bundle',EXP/'component-audit'/(args.case+'.json'))
|
||||||
|
budget()
|
||||||
|
print(json.dumps(dict(backend=args.backend,case=args.case,repeat=args.repeat,
|
||||||
|
complete=result.get('complete'),pass_all=result.get('pass_all')),allow_nan=False),flush=True)
|
||||||
|
if not result.get('pass_all',False):raise SystemExit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
"""Ordered numerical gates before any full CAL; never tune from outcomes."""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
from context import ROOT,MODEL,EXP,CFG,check,save,budget
|
||||||
|
|
||||||
|
SCIENCE=ROOT/'models/male-cns-lif/.venv/bin/python'
|
||||||
|
ORACLE=ROOT/'experiments/phase4ad-author-semantics/environment/.venv/bin/python'
|
||||||
|
|
||||||
|
|
||||||
|
def child(backend,name,repeat=0):
|
||||||
|
log=EXP/'logs'/f'{backend}-{name}-r{repeat}.log'
|
||||||
|
cmd=[str(ORACLE if backend=='oracle' else SCIENCE),'-B',str(MODEL/'run_case.py'),backend,name,'--repeat',str(repeat)]
|
||||||
|
print('START',backend,name,repeat,flush=True);t0=time.perf_counter()
|
||||||
|
with log.open('x',encoding='utf-8') as f:
|
||||||
|
result=subprocess.run(cmd,stdout=f,stderr=subprocess.STDOUT,timeout=1800,check=False)
|
||||||
|
print('FINISH',backend,name,repeat,'exit',result.returncode,'wall',round(time.perf_counter()-t0,2),flush=True)
|
||||||
|
if result.returncode:raise RuntimeError(f'{backend} {name} failed; inspect {log}')
|
||||||
|
|
||||||
|
|
||||||
|
def gate_case(name,repeats):
|
||||||
|
from compare import compare,compare_gpu_repeats
|
||||||
|
child('gpu',name)
|
||||||
|
for r in range(1,repeats):child('gpu',name,r)
|
||||||
|
child('oracle',name)
|
||||||
|
result=compare(EXP/'cases'/name,EXP/'gpu'/(name+'-r0'),EXP/'oracle'/name,EXP/'audit'/('compare-'+name+'.json'))
|
||||||
|
assert result['pass_all'],f'Closed-loop exact comparison failed: {name}; no later CAL permitted'
|
||||||
|
for r in range(1,repeats):
|
||||||
|
report=compare_gpu_repeats(EXP/'gpu'/(name+'-r0'),EXP/'gpu'/f'{name}-r{r}',EXP/'audit'/f'repeat-{name}-r{r}.json')
|
||||||
|
assert report['pass_all'],f'Exact GPU repeat failed: {name}'
|
||||||
|
child('component',name)
|
||||||
|
return dict(case=name,pass_all=True,gpu_repeats=repeats)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser=argparse.ArgumentParser();parser.add_argument('stage',choices=['fixtures','probes','calibration']);args=parser.parse_args()
|
||||||
|
check();budget();receipt=EXP/'audit'/(args.stage+'-gate.json');assert not receipt.exists()
|
||||||
|
try:
|
||||||
|
if args.stage=='fixtures':
|
||||||
|
rows=[gate_case(n,CFG['fixture_repeats']) for n in CFG['fixtures']]
|
||||||
|
save(receipt,dict(pass_all=True,cases=rows,scope='Fixed real-edge induced fixtures only'))
|
||||||
|
elif args.stage=='probes':
|
||||||
|
assert json.loads((EXP/'audit/fixtures-gate.json').read_text())['pass_all']
|
||||||
|
rows=[gate_case(n,1) for n in CFG['calibration']['full_oracle_probes']]
|
||||||
|
save(receipt,dict(pass_all=True,cases=rows,scope='Only two original first-CAL fixed fullgraph trajectories'))
|
||||||
|
else:
|
||||||
|
assert json.loads((EXP/'audit/fixtures-gate.json').read_text())['pass_all']
|
||||||
|
assert json.loads((EXP/'audit/probes-gate.json').read_text())['pass_all']
|
||||||
|
records=json.loads((EXP/'protocol/calibration-cases.json').read_text());assert len(records)==60
|
||||||
|
probes=CFG['calibration']['full_oracle_probes']
|
||||||
|
for rec in records:
|
||||||
|
if rec['name'] not in probes:child('gpu',rec['name'])
|
||||||
|
if rec['seed']==CFG['calibration']['seeds'][0]:child('gpu',rec['name'],1)
|
||||||
|
from calibration import summarize
|
||||||
|
result=summarize()
|
||||||
|
save(receipt,dict(pass_all=result['pass_all'],scope='Complete original six-CAL representation gate, not heldout or learning',summary='calibration/summary.json'))
|
||||||
|
if not result['pass_all']:raise SystemExit(2)
|
||||||
|
except Exception as e:
|
||||||
|
save(EXP/'audit'/('stopped-'+args.stage+'.json'),dict(stage=args.stage,type=type(e).__name__,message=str(e),traceback=traceback.format_exc(),
|
||||||
|
later_stages_not_permitted=True,partial_outputs_preserved=True,parameters_changed=False))
|
||||||
|
raise
|
||||||
|
budget()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
"""Local, synthetic tests only: no CUDA, scientific trajectories, or heldout data."""
|
||||||
|
import copy
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from calibration import (ORIGINAL_MODES, ORIGINAL_SEEDS, ORIGINAL_CAL_IDS,
|
||||||
|
APL_FILES, STATE_DTYPES, arrays_bitwise_equal, evaluate_gates, exact_repeat, pair_metrics,
|
||||||
|
sample_cv, summarize_mode, validate_inventory, validate_state)
|
||||||
|
|
||||||
|
|
||||||
|
GATES = {"sparse_min_fraction": .03, "sparse_max_fraction": .09,
|
||||||
|
"minimum_separable_odor_pairs": 3, "max_fraction_strict": .5, "min_fraction_strict": 0.,
|
||||||
|
"same_jaccard_gt_between": True, "between_euclidean_gt_within": True,
|
||||||
|
"both_modes_required": True, "finite_required": True, "repeat_exact_required": True}
|
||||||
|
|
||||||
|
|
||||||
|
def synthetic_runs(silent=False):
|
||||||
|
result = {}
|
||||||
|
for mode in ORIGINAL_MODES:
|
||||||
|
for odor in range(6):
|
||||||
|
for seed in ORIGINAL_SEEDS:
|
||||||
|
counts = np.zeros(1000, dtype=np.int32)
|
||||||
|
if not silent:
|
||||||
|
counts[odor * 50:(odor + 1) * 50] = 1
|
||||||
|
result[(mode, str(odor), seed)] = {"kc_counts": counts,
|
||||||
|
"expected_external_events": 10., "external_events": 0 if silent else 10}
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class CalibrationTests(unittest.TestCase):
|
||||||
|
def test_complete_gate_and_original_pair_counts(self):
|
||||||
|
summary = summarize_mode(ORIGINAL_MODES[0], list(map(str, range(6))), ORIGINAL_SEEDS, synthetic_runs(), GATES)
|
||||||
|
self.assertTrue(summary["gate"])
|
||||||
|
self.assertEqual(summary["within_distance_count"], 60)
|
||||||
|
self.assertEqual(summary["between_distance_count"], 75)
|
||||||
|
self.assertEqual(summary["pair_count"], 15)
|
||||||
|
self.assertEqual(summary["pairwise_separation_pass_count"], 15)
|
||||||
|
self.assertTrue(all(row["within_distance_count"] == 20 and row["between_distance_count"] == 5 for row in summary["pairs"]))
|
||||||
|
|
||||||
|
def test_silent_is_not_pass(self):
|
||||||
|
summary = summarize_mode(ORIGINAL_MODES[0], list(map(str, range(6))), ORIGINAL_SEEDS, synthetic_runs(True), GATES)
|
||||||
|
self.assertFalse(summary["gate"])
|
||||||
|
self.assertFalse(summary["conditions"]["minimum_strictly_positive"])
|
||||||
|
self.assertFalse(summary["conditions"]["same_jaccard_gt_different"])
|
||||||
|
self.assertFalse(summary["conditions"]["different_euclidean_gt_same"])
|
||||||
|
self.assertEqual(summary["pairwise_separation_pass_count"], 0)
|
||||||
|
self.assertIsNone(summary["actual_event_count_cv"])
|
||||||
|
|
||||||
|
def test_every_original_conjunct_is_necessary(self):
|
||||||
|
baseline = summarize_mode(ORIGINAL_MODES[0], list(map(str, range(6))), ORIGINAL_SEEDS, synthetic_runs(), GATES)
|
||||||
|
changes = (("KC_active_fraction_mean", .029), ("KC_active_fraction_mean", .091),
|
||||||
|
("KC_active_fraction_max", .5), ("KC_active_fraction_min", 0.),
|
||||||
|
("same_odor_jaccard_mean", baseline["different_odor_jaccard_mean"]),
|
||||||
|
("different_odor_euclidean_mean", baseline["same_odor_euclidean_mean"]),
|
||||||
|
("pairwise_separation_pass_count", 2))
|
||||||
|
for key, value in changes:
|
||||||
|
with self.subTest(key=key, value=value):
|
||||||
|
modified = dict(baseline, **{key: value})
|
||||||
|
self.assertFalse(all(evaluate_gates(modified, GATES).values()))
|
||||||
|
for value in (.03, .09):
|
||||||
|
self.assertTrue(evaluate_gates(dict(baseline, KC_active_fraction_mean=value), GATES)["mean_sparsity_in_closed_interval"])
|
||||||
|
|
||||||
|
def test_pair_specific_not_global_baseline(self):
|
||||||
|
runs = synthetic_runs()
|
||||||
|
mode = ORIGINAL_MODES[0]
|
||||||
|
for odor in range(6):
|
||||||
|
for index, seed in enumerate(ORIGINAL_SEEDS):
|
||||||
|
counts = np.array([index + odor * 100] if odor < 2 else [10000 * odor + index * 1000], dtype=np.int32)
|
||||||
|
runs[(mode, str(odor), seed)]["kc_counts"] = counts
|
||||||
|
summary = summarize_mode(mode, list(map(str, range(6))), ORIGINAL_SEEDS, runs, GATES)
|
||||||
|
first_pair = summary["pairs"][0]
|
||||||
|
self.assertEqual(first_pair["within_this_pair_mean"], 2.)
|
||||||
|
self.assertEqual(first_pair["between_same_seed_mean"], 100.)
|
||||||
|
self.assertTrue(first_pair["gate"])
|
||||||
|
self.assertGreater(summary["same_odor_euclidean_mean"], 100.)
|
||||||
|
|
||||||
|
def test_original_metric_zero_and_count_semantics(self):
|
||||||
|
zero = np.zeros(3, dtype=np.int32)
|
||||||
|
self.assertEqual(pair_metrics(zero, zero)["active_jaccard"], 1.)
|
||||||
|
self.assertEqual(pair_metrics(zero, zero)["correlation"], 1.)
|
||||||
|
result = pair_metrics(np.array([2, 0, 0]), np.array([1, 0, 0]))
|
||||||
|
self.assertEqual(result["euclidean_distance"], 1.)
|
||||||
|
self.assertEqual(result["active_jaccard"], 1.)
|
||||||
|
self.assertAlmostEqual(sample_cv([1., 2., 3.]), .5)
|
||||||
|
|
||||||
|
def test_repeat_comparison_is_bits_and_dtype(self):
|
||||||
|
self.assertFalse(arrays_bitwise_equal(np.array([0.], np.float64), np.array([-0.], np.float64)))
|
||||||
|
self.assertFalse(arrays_bitwise_equal(np.array([1], np.int32), np.array([1], np.int64)))
|
||||||
|
self.assertTrue(arrays_bitwise_equal(np.array([1.], np.float32), np.array([1.], np.float32)))
|
||||||
|
|
||||||
|
def test_exact_repeat_covers_all_recorded_semantics(self):
|
||||||
|
first = {"state": {name: np.zeros(1, dtype) for name, dtype in STATE_DTYPES.items()},
|
||||||
|
"apl": {name: np.zeros((1, width), np.float32) for name, width in APL_FILES.items()},
|
||||||
|
"hashes": [{"tick": 0}], "queues": [{"tick": 0}],
|
||||||
|
"requests": [], "component": {"environment": {"tf32": False}}}
|
||||||
|
self.assertTrue(exact_repeat(first, copy.deepcopy(first))["pass_all"])
|
||||||
|
for category in ("state", "apl"):
|
||||||
|
for name in first[category]:
|
||||||
|
bad = copy.deepcopy(first)
|
||||||
|
bad[category][name].flat[0] = 1
|
||||||
|
with self.subTest(category=category, name=name):
|
||||||
|
self.assertFalse(exact_repeat(first, bad)["pass_all"])
|
||||||
|
for key in ("hashes", "queues", "requests", "component"):
|
||||||
|
bad = copy.deepcopy(first)
|
||||||
|
bad[key] = {} if isinstance(first[key], list) else []
|
||||||
|
with self.subTest(key=key):
|
||||||
|
self.assertFalse(exact_repeat(first, bad)["pass_all"])
|
||||||
|
|
||||||
|
def test_raw_state_rejects_nonfinite_duplicate_and_wrong_counts(self):
|
||||||
|
state = {"step": np.array([0], np.int32), "neuron_idx": np.array([1], np.int32),
|
||||||
|
"counts": np.array([0, 1], np.int32), "v": np.zeros(2, np.float64),
|
||||||
|
"g": np.zeros(2, np.float64), "ref": np.zeros(2, np.int32)}
|
||||||
|
validate_state(state, 2, 10)
|
||||||
|
for mutation in ("nan", "counts", "duplicate", "wrong_dtype"):
|
||||||
|
bad = copy.deepcopy(state)
|
||||||
|
if mutation == "nan": bad["g"][0] = np.nan
|
||||||
|
if mutation == "counts": bad["counts"][0] = 1
|
||||||
|
if mutation == "duplicate":
|
||||||
|
bad["step"] = np.array([0, 0], np.int32)
|
||||||
|
bad["neuron_idx"] = np.array([1, 1], np.int32)
|
||||||
|
bad["counts"][1] = 2
|
||||||
|
if mutation == "wrong_dtype": bad["v"] = bad["v"].astype(np.float32)
|
||||||
|
with self.subTest(mutation=mutation), self.assertRaises(ValueError):
|
||||||
|
validate_state(bad, 2, 10)
|
||||||
|
|
||||||
|
def test_inventory_rejects_missing_duplicate_or_heldout_identity(self):
|
||||||
|
odors = sorted(ORIGINAL_CAL_IDS)
|
||||||
|
records = [{"name": f"cal-{mode}-{index:02d}-s{seed}", "mode": mode, "odor_index": index,
|
||||||
|
"odor_id": odors[index], "seed": seed} for mode in ORIGINAL_MODES
|
||||||
|
for index in range(6) for seed in ORIGINAL_SEEDS]
|
||||||
|
cfg = {"calibration": {"modes": list(ORIGINAL_MODES), "seeds": list(ORIGINAL_SEEDS),
|
||||||
|
"duration_ms": 100., "odor_count": 6, "split": "calibration", "repeat_first_seed_each_odor": True}, "gates": GATES}
|
||||||
|
self.assertEqual(validate_inventory(records, cfg), odors)
|
||||||
|
for malformed in (records[:-1], records[:-1] + [records[0]],
|
||||||
|
[dict(row, odor_id="heldout") if row["odor_index"] == 0 else row for row in records]):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validate_inventory(malformed, cfg)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
"""Local/remote pure protocol tests; no Brian, Torch, GPU or network execution.
|
||||||
|
|
||||||
|
Run with the already-provisioned Python and ``-B test_protocol.py``. The
|
||||||
|
sidecar process is mocked with in-memory stdin and an anonymous stdout pipe.
|
||||||
|
These tests validate transport and declared arithmetic/input contracts, not
|
||||||
|
the scientific trajectory or independent correctness of the Torch component.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import types
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
HERE = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
|
||||||
|
def load_no_cache(path, name):
|
||||||
|
module = types.ModuleType(name)
|
||||||
|
module.__file__ = str(path)
|
||||||
|
exec(compile(path.read_bytes(), str(path), "exec"), module.__dict__)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
ORACLE = load_no_cache(HERE / "oracle_apl.py", "phase4ag_protocol_oracle")
|
||||||
|
|
||||||
|
|
||||||
|
def handshake(**updates):
|
||||||
|
result = {"ok": True, "protocol": "phase4ag-apl-v1", "n_neurons": 166700,
|
||||||
|
"n_apl": 2, "n_kc": 4064, "dt_ms": .1,
|
||||||
|
"files_sha256": {name: "frozen-test-hash" for name in ORACLE.BUNDLE_FILES},
|
||||||
|
"decay_f32_bits": f"{int(np.float32(math.exp(-.1 / 20.)).view(np.uint32)):08x}",
|
||||||
|
"gain_f32_bits": f"{int(np.float32(.01).view(np.uint32)):08x}"}
|
||||||
|
result.update(updates)
|
||||||
|
return (json.dumps(result) + "\n").encode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def frame(tick=0, values=None, byte_count=None):
|
||||||
|
values = np.arange(4068, dtype="<f4") if values is None else np.asarray(values, dtype="<f4")
|
||||||
|
count = values.nbytes if byte_count is None else byte_count
|
||||||
|
return struct.pack("<qQ", tick, count) + values.tobytes()
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryInput(io.BytesIO):
|
||||||
|
def close(self):
|
||||||
|
if not self.closed:
|
||||||
|
self.closed_data = self.getvalue()
|
||||||
|
super().close()
|
||||||
|
|
||||||
|
|
||||||
|
class FakeProcess:
|
||||||
|
"""The only use of OS descriptors is an anonymous read-only response pipe."""
|
||||||
|
def __init__(self, response, status=0, chunk_size=97):
|
||||||
|
read_fd, write_fd = os.pipe()
|
||||||
|
self.stdin = MemoryInput()
|
||||||
|
self.stdout = os.fdopen(read_fd, "rb", buffering=0)
|
||||||
|
self.status = status
|
||||||
|
self.terminated = False
|
||||||
|
|
||||||
|
def write_response():
|
||||||
|
try:
|
||||||
|
for begin in range(0, len(response), chunk_size):
|
||||||
|
view = memoryview(response[begin:begin + chunk_size])
|
||||||
|
while view:
|
||||||
|
view = view[os.write(write_fd, view):]
|
||||||
|
except (BrokenPipeError, OSError):
|
||||||
|
# Invalid-response tests deliberately close the reader early.
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
os.close(write_fd)
|
||||||
|
|
||||||
|
self.thread = threading.Thread(target=write_response, daemon=True)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def poll(self):
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
def wait(self, timeout=None):
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
self.terminated = True
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
self.terminated = True
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if not self.stdin.closed:
|
||||||
|
self.stdin.close()
|
||||||
|
if not self.stdout.closed:
|
||||||
|
self.stdout.close()
|
||||||
|
self.thread.join(timeout=2)
|
||||||
|
|
||||||
|
|
||||||
|
class ProtocolTests(unittest.TestCase):
|
||||||
|
def create_worker(self, response, status=0):
|
||||||
|
process = FakeProcess(response, status=status)
|
||||||
|
self.addCleanup(process.close)
|
||||||
|
source_patch = mock.patch.object(ORACLE, "_digest", return_value="frozen-test-hash")
|
||||||
|
process_patch = mock.patch.object(ORACLE.subprocess, "Popen", return_value=process)
|
||||||
|
source_patch.start()
|
||||||
|
process_mock = process_patch.start()
|
||||||
|
self.addCleanup(source_patch.stop)
|
||||||
|
self.addCleanup(process_patch.stop)
|
||||||
|
worker = ORACLE._APLWorker(Path("science-python"), Path("legacy_apl_worker.py"), Path("bundle"), None, timeout=2)
|
||||||
|
self.addCleanup(worker.abort)
|
||||||
|
return worker, process, process_mock
|
||||||
|
|
||||||
|
def test_exact_handshake_frame_and_clean_eof(self):
|
||||||
|
worker, process, process_mock = self.create_worker(handshake() + frame())
|
||||||
|
globals_ = np.array([1, 40, 166699], dtype=np.int32)
|
||||||
|
drive, state, inhibition = worker.step(0, globals_)
|
||||||
|
values = np.arange(4068, dtype=np.float32)
|
||||||
|
np.testing.assert_array_equal(drive, values[:2])
|
||||||
|
np.testing.assert_array_equal(state, values[2:4])
|
||||||
|
np.testing.assert_array_equal(inhibition, values[4:])
|
||||||
|
request = process.stdin.getvalue()
|
||||||
|
self.assertEqual(struct.unpack("<qQ", request[:16]), (0, 3))
|
||||||
|
np.testing.assert_array_equal(np.frombuffer(request[16:], dtype="<i4"), globals_)
|
||||||
|
self.assertEqual(worker.finish(1), 0)
|
||||||
|
command = process_mock.call_args.args[0]
|
||||||
|
self.assertEqual(command, ["science-python", "-B", "legacy_apl_worker.py", "--bundle-dir", "bundle", "--dt-ms", "0.1"])
|
||||||
|
self.assertFalse(process_mock.call_args.kwargs["shell"])
|
||||||
|
|
||||||
|
def test_empty_spike_frame_still_advances_one_tick(self):
|
||||||
|
worker, process, _ = self.create_worker(handshake() + frame(values=np.zeros(4068, np.float32)))
|
||||||
|
arrays = worker.step(0, np.empty(0, np.int32))
|
||||||
|
self.assertTrue(all(np.all(value == 0) for value in arrays))
|
||||||
|
self.assertEqual(process.stdin.getvalue(), struct.pack("<qQ", 0, 0))
|
||||||
|
self.assertEqual(worker.finish(1), 0)
|
||||||
|
|
||||||
|
def test_two_consecutive_ticks(self):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame(0) + frame(1))
|
||||||
|
worker.step(0, np.array([4], np.int32))
|
||||||
|
worker.step(1, np.array([8, 10], np.int32))
|
||||||
|
self.assertEqual(worker.finish(2), 0)
|
||||||
|
|
||||||
|
def test_rejects_wrong_protocol_or_dimensions(self):
|
||||||
|
for update in ({"protocol": "other"}, {"ok": False}, {"n_neurons": 42},
|
||||||
|
{"n_kc": 3}, {"dt_ms": .2}, {"gain_f32_bits": "00000000"},
|
||||||
|
{"files_sha256": {}}):
|
||||||
|
with self.subTest(update=update):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.create_worker(handshake(**update))
|
||||||
|
|
||||||
|
def test_rejects_wrong_tick_or_payload_length(self):
|
||||||
|
for response in (frame(tick=1), frame(byte_count=8)):
|
||||||
|
with self.subTest(response_header=response[:16]):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + response)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
|
||||||
|
def test_rejects_truncated_response(self):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame()[:-1])
|
||||||
|
with self.assertRaises(EOFError):
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
|
||||||
|
def test_rejects_nonfinite_or_negative_apl_payload(self):
|
||||||
|
for bad_value in (np.nan, np.inf, -1):
|
||||||
|
with self.subTest(value=bad_value):
|
||||||
|
values = np.zeros(4068, np.float32)
|
||||||
|
values[-1] = bad_value
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame(values=values))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
|
||||||
|
def test_rejects_invalid_spike_dtype_order_and_range(self):
|
||||||
|
for values in (np.array([1], np.int64), np.array([2, 1], np.int32),
|
||||||
|
np.array([1, 1], np.int32), np.array([-1], np.int32),
|
||||||
|
np.array([166700], np.int32)):
|
||||||
|
with self.subTest(values=values):
|
||||||
|
worker, process, _ = self.create_worker(handshake() + frame())
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(0, values)
|
||||||
|
self.assertEqual(process.stdin.getvalue(), b"")
|
||||||
|
|
||||||
|
def test_rejects_skipped_request_tick(self):
|
||||||
|
worker, process, _ = self.create_worker(handshake() + frame())
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(1, np.empty(0, np.int32))
|
||||||
|
self.assertEqual(process.stdin.getvalue(), b"")
|
||||||
|
|
||||||
|
def test_rejects_failed_exit_and_trailing_stdout(self):
|
||||||
|
for suffix, status in ((b"", 7), (b"unexpected", 0)):
|
||||||
|
with self.subTest(status=status, suffix=suffix):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame() + suffix, status=status)
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.finish(1)
|
||||||
|
|
||||||
|
def test_pipe_reader_timeout(self):
|
||||||
|
read_fd, write_fd = os.pipe()
|
||||||
|
stream = os.fdopen(read_fd, "rb", buffering=0)
|
||||||
|
reader = ORACLE._PipeReader(stream, .05)
|
||||||
|
try:
|
||||||
|
with self.assertRaises(TimeoutError):
|
||||||
|
reader.read(1)
|
||||||
|
finally:
|
||||||
|
os.close(write_fd)
|
||||||
|
reader.thread.join(timeout=2)
|
||||||
|
stream.close()
|
||||||
|
self.assertFalse(reader.thread.is_alive())
|
||||||
|
|
||||||
|
|
||||||
|
class ArithmeticAndIdentityContractTests(unittest.TestCase):
|
||||||
|
def test_si_conversion_must_follow_float64_promotion(self):
|
||||||
|
h32 = np.array([.01, 1 / 7, 123.456], dtype=np.float32)
|
||||||
|
correct = h32.astype(np.float64) * np.float64(.001)
|
||||||
|
early_conversion = (h32 * np.float32(.001)).astype(np.float64)
|
||||||
|
self.assertFalse(np.array_equal(correct.view(np.uint64), early_conversion.view(np.uint64)))
|
||||||
|
for actual, original in zip(correct, h32):
|
||||||
|
self.assertEqual(actual.hex(), (float(original) * float(.001)).hex())
|
||||||
|
|
||||||
|
def test_declared_overlay_does_not_guard_refractory_targets(self):
|
||||||
|
before = np.array([0, -.002, .001], dtype=np.float64)
|
||||||
|
refractory = np.array([22, 21, 0], dtype=np.int32)
|
||||||
|
h32 = np.array([1, 2, 3], dtype=np.float32)
|
||||||
|
delta = h32.astype(np.float64) * np.float64(.001)
|
||||||
|
after = before - delta
|
||||||
|
self.assertTrue(np.all(after != before))
|
||||||
|
np.testing.assert_array_equal(refractory, [22, 21, 0])
|
||||||
|
self.assertEqual(after[0], -.001)
|
||||||
|
|
||||||
|
def test_af_queue_hash_keeps_original_noncontiguous_ids_and_rejections(self):
|
||||||
|
path = HERE.parent / "author-fullgraph-lab-v1" / "oracle_full.py"
|
||||||
|
self.assertEqual(hashlib.sha256(path.read_bytes()).hexdigest(), ORACLE.AF_SHA256)
|
||||||
|
af = load_no_cache(path, "phase4ag_protocol_af")
|
||||||
|
edges = np.array([81, 2, 500], dtype=np.int64)
|
||||||
|
accepted = np.array([1, 0, 1], dtype=np.uint8)
|
||||||
|
original_edges, original_mask = edges.copy(), accepted.copy()
|
||||||
|
result = af.queue_summary(18, edges, accepted, chunk_bytes=8)
|
||||||
|
packet = b"phase4af-queue-v1\0" + struct.pack("<qq", 18, 3) + edges.astype("<i8").tobytes() + accepted.tobytes()
|
||||||
|
self.assertEqual(result["joint_sha256"], hashlib.sha256(packet).hexdigest())
|
||||||
|
self.assertEqual((result["count"], result["accepted_count"]), (3, 2))
|
||||||
|
self.assertEqual(result, af.queue_summary(18, edges, accepted, chunk_bytes=8192))
|
||||||
|
np.testing.assert_array_equal(edges, original_edges)
|
||||||
|
np.testing.assert_array_equal(accepted, original_mask)
|
||||||
|
|
||||||
|
def test_empty_queue_hash_includes_tick(self):
|
||||||
|
af = load_no_cache(HERE.parent / "author-fullgraph-lab-v1" / "oracle_full.py", "phase4ag_empty_af")
|
||||||
|
first = af.queue_summary(0, np.empty(0, np.int64), np.empty(0, np.uint8))
|
||||||
|
second = af.queue_summary(1, np.empty(0, np.int64), np.empty(0, np.uint8))
|
||||||
|
self.assertEqual(first["ordered_edge_sha256"], hashlib.sha256(b"").hexdigest())
|
||||||
|
self.assertNotEqual(first["joint_sha256"], second["joint_sha256"])
|
||||||
|
|
||||||
|
def test_oracle_import_has_no_brian_or_torch_dependency(self):
|
||||||
|
before = set(sys.modules)
|
||||||
|
load_no_cache(HERE / "oracle_apl.py", "phase4ag_second_import")
|
||||||
|
added = set(sys.modules) - before
|
||||||
|
self.assertFalse(any(name == "brian2" or name.startswith("brian2.") or
|
||||||
|
name == "torch" or name.startswith("torch.") for name in added))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main(verbosity=2)
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
"""Independent extraction/replay of the frozen legacy APL component.
|
||||||
|
|
||||||
|
Only the initializer prefix before ``self.base`` and two original APL update
|
||||||
|
statements are executed. No old simulator is instantiated, no learning code is
|
||||||
|
executed, and no frozen artifact is written. The Torch replay is a component
|
||||||
|
oracle, not an independent CPU whole-brain closed-loop oracle.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import ast
|
||||||
|
import copy
|
||||||
|
from functools import lru_cache
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import types
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pyarrow.parquet as pq
|
||||||
|
import torch
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path('/data/digital-drosophila')
|
||||||
|
CANONICAL = ROOT/'datasets/male-cns-v1.0/processed/neuron-only'
|
||||||
|
SOURCE = ROOT/'models/male-cns-lif/deterministic-runtime-v2/phase4p_revalidate.py'
|
||||||
|
SOURCE_SHA256 = 'c7e693a2da70acdce4f53af5c2853e52e8333acc93f88a46a5e8083eac639346'
|
||||||
|
N, A, K = 166700, 2, 4064
|
||||||
|
BUNDLE_ARRAYS = {
|
||||||
|
'input_matrix': (np.float32, (A, N)), 'output_matrix': (np.float32, (A, K)),
|
||||||
|
'input_raw': (np.float32, (A, N)), 'output_raw': (np.float32, (A, K)),
|
||||||
|
'kc_globals': (np.int32, (K,)), 'apl_globals': (np.int32, (A,)),
|
||||||
|
'pn_globals': (np.int32, None), 'apl_out_ids': (np.int64, (5845,)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def digest(path):
|
||||||
|
h = hashlib.sha256()
|
||||||
|
with Path(path).open('rb') as source:
|
||||||
|
for block in iter(lambda: source.read(8 << 20), b''):
|
||||||
|
h.update(block)
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def array_hash(value):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def bit_equal(a, b):
|
||||||
|
a, b = np.asarray(a), np.asarray(b)
|
||||||
|
return bool(a.dtype == b.dtype and a.shape == b.shape and
|
||||||
|
np.array_equal(np.ascontiguousarray(a).view(np.uint8),
|
||||||
|
np.ascontiguousarray(b).view(np.uint8)))
|
||||||
|
|
||||||
|
|
||||||
|
def save(path, value):
|
||||||
|
path = Path(path)
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with path.open('x', encoding='utf-8') as target:
|
||||||
|
json.dump(value, target, indent=2, sort_keys=True, allow_nan=False)
|
||||||
|
target.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
class ReadOnlyNamespace:
|
||||||
|
"""The extracted prefix can read rt, but cannot mutate or add rt fields."""
|
||||||
|
def __init__(self, **values):
|
||||||
|
object.__setattr__(self, '_values', types.MappingProxyType(values))
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return self._values[name]
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
raise AttributeError('Read-only canonical runtime view')
|
||||||
|
|
||||||
|
|
||||||
|
def _code(nodes, filename):
|
||||||
|
module = ast.Module(body=copy.deepcopy(nodes), type_ignores=[])
|
||||||
|
return compile(ast.fix_missing_locations(module), str(filename), 'exec')
|
||||||
|
|
||||||
|
|
||||||
|
def _self_attribute(target, field):
|
||||||
|
return isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name) and \
|
||||||
|
target.value.id == 'self' and target.attr == field
|
||||||
|
|
||||||
|
|
||||||
|
def extract_statements():
|
||||||
|
data = SOURCE.read_bytes()
|
||||||
|
require(hashlib.sha256(data).hexdigest() == SOURCE_SHA256, 'Frozen legacy source SHA-256 mismatch')
|
||||||
|
text = data.decode('utf-8')
|
||||||
|
tree = ast.parse(text, filename=str(SOURCE))
|
||||||
|
classes = [node for node in tree.body if isinstance(node, ast.ClassDef) and node.name == 'DeterministicAPLSim']
|
||||||
|
require(len(classes) == 1, 'Expected exactly one frozen DeterministicAPLSim')
|
||||||
|
methods = {node.name: node for node in classes[0].body if isinstance(node, ast.FunctionDef)}
|
||||||
|
init, run = methods['__init__'], methods['run']
|
||||||
|
cuts = [i for i, node in enumerate(init.body) if isinstance(node, ast.Assign) and
|
||||||
|
any(_self_attribute(target, 'base') for target in node.targets)]
|
||||||
|
require(len(cuts) == 1 and cuts[0] > 0, 'Missing/ambiguous self.base cutoff')
|
||||||
|
prefix = init.body[:cuts[0]]
|
||||||
|
# Executing no import or file-writing call is allowed in the extracted prefix.
|
||||||
|
require(not any(isinstance(node, (ast.Import, ast.ImportFrom, ast.With, ast.AsyncWith))
|
||||||
|
for stmt in prefix for node in ast.walk(stmt)), 'Unexpected side-effect construct in initializer prefix')
|
||||||
|
expressions = [node for node in ast.walk(run) if isinstance(node, ast.Expr) and
|
||||||
|
isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Attribute) and
|
||||||
|
node.value.func.attr == 'add_' and isinstance(node.value.func.value, ast.Call) and
|
||||||
|
isinstance(node.value.func.value.func, ast.Attribute) and
|
||||||
|
isinstance(node.value.func.value.func.value, ast.Name) and
|
||||||
|
node.value.func.value.func.value.id == 'apl_state' and node.value.func.value.func.attr == 'mul_']
|
||||||
|
inhibition = [node for node in ast.walk(run) if isinstance(node, ast.Assign) and
|
||||||
|
any(isinstance(target, ast.Name) and target.id == 'inhibition' for target in node.targets)]
|
||||||
|
decay = [node for node in ast.walk(run) if isinstance(node, ast.Assign) and
|
||||||
|
any(isinstance(target, ast.Name) and target.id == 'apl_decay' for target in node.targets)]
|
||||||
|
require(len(expressions) == len(inhibition) == len(decay) == 1, 'Ambiguous frozen APL operator extraction')
|
||||||
|
require(expressions[0].lineno < inhibition[0].lineno, 'Unexpected frozen APL update order')
|
||||||
|
rhs = inhibition[0].value
|
||||||
|
require(isinstance(rhs, ast.BinOp) and isinstance(rhs.op, ast.Mult), 'Unexpected inhibition gain expression')
|
||||||
|
gain_expression = ast.Expression(copy.deepcopy(rhs.right))
|
||||||
|
provenance = {'source': str(SOURCE), 'sha256': SOURCE_SHA256,
|
||||||
|
'initializer_line_start': prefix[0].lineno, 'initializer_line_end': prefix[-1].end_lineno,
|
||||||
|
'excluded_self_base_line': init.body[cuts[0]].lineno,
|
||||||
|
'decay_line': decay[0].lineno, 'state_update_line': expressions[0].lineno,
|
||||||
|
'inhibition_line': inhibition[0].lineno,
|
||||||
|
'initializer_source': '\n'.join(ast.get_source_segment(text, node) for node in prefix),
|
||||||
|
'decay_source': ast.get_source_segment(text, decay[0]),
|
||||||
|
'state_update_source': ast.get_source_segment(text, expressions[0]),
|
||||||
|
'inhibition_source': ast.get_source_segment(text, inhibition[0]),
|
||||||
|
'learning_initializer_suffix_executed': False, 'original_run_loop_executed': False}
|
||||||
|
return (_code(prefix, SOURCE), _code(decay, SOURCE),
|
||||||
|
_code([expressions[0], inhibition[0]], SOURCE),
|
||||||
|
compile(ast.fix_missing_locations(gain_expression), str(SOURCE), 'eval'), provenance)
|
||||||
|
|
||||||
|
|
||||||
|
def _canonical_files():
|
||||||
|
return {name: CANONICAL/path for name, path in {
|
||||||
|
'metadata': 'neuron-index/unified-metadata.parquet',
|
||||||
|
'indptr': 'gpu/csr-indptr.int64.npy', 'indices': 'gpu/csr-indices.int32.npy',
|
||||||
|
'raw': 'gpu/csr-weights.int64.npy'}.items()}
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=2)
|
||||||
|
def reconstruct(canonical_hashes, device_name):
|
||||||
|
"""Cache only reconstructions tied to exact canonical bytes and source hash."""
|
||||||
|
files = _canonical_files()
|
||||||
|
require(dict(canonical_hashes) == {name: digest(path) for name, path in files.items()},
|
||||||
|
'Canonical bytes changed before matrix reconstruction')
|
||||||
|
arrays = {name: np.load(files[name], mmap_mode='r', allow_pickle=False)
|
||||||
|
for name in ('indptr', 'indices', 'raw')}
|
||||||
|
require(arrays['indptr'].dtype == np.int64 and arrays['indices'].dtype == np.int32 and
|
||||||
|
arrays['raw'].dtype == np.int64, 'Canonical CSR dtypes changed')
|
||||||
|
require(arrays['indptr'].shape == (N + 1,) and arrays['indptr'][-1] == 25582938 and
|
||||||
|
arrays['indices'].shape == arrays['raw'].shape == (25582938,), 'Canonical graph shape changed')
|
||||||
|
require(int(arrays['raw'].sum()) == 124177617 and bool(np.all(arrays['raw'] > 0)), 'Canonical raw weights changed')
|
||||||
|
table = pq.read_table(files['metadata'])
|
||||||
|
require(table.num_rows == N, 'Canonical metadata count changed')
|
||||||
|
rt = ReadOnlyNamespace(n=N, dt=.1, device=torch.device(device_name), table=table,
|
||||||
|
indptr_np=arrays['indptr'], indices_np=arrays['indices'], raw_np=arrays['raw'])
|
||||||
|
view = types.SimpleNamespace()
|
||||||
|
init_code, decay_code, update_code, gain_code, provenance = extract_statements()
|
||||||
|
scope = {'self': view, 'rt': rt, 'np': np, 'torch': torch}
|
||||||
|
exec(init_code, scope)
|
||||||
|
require(not hasattr(view, 'base') and not hasattr(view, 'identity'), 'Initializer crossed the learning cutoff')
|
||||||
|
expected = {'input_matrix': view.input_gpu.detach().cpu().numpy().copy(),
|
||||||
|
'output_matrix': view.output_gpu.detach().cpu().numpy().copy(),
|
||||||
|
'input_raw': scope['input_matrix'], 'output_raw': scope['output_matrix'],
|
||||||
|
'kc_globals': view.kc, 'apl_globals': view.apl, 'pn_globals': view.pn,
|
||||||
|
'apl_out_ids': view.apl_out_ids}
|
||||||
|
for value in expected.values():
|
||||||
|
value.flags.writeable = False
|
||||||
|
return view, expected, provenance, (decay_code, update_code, gain_code)
|
||||||
|
|
||||||
|
|
||||||
|
class TorchObservationProxy:
|
||||||
|
"""Observe the result of the actual extracted torch.mv call unchanged."""
|
||||||
|
def __init__(self):
|
||||||
|
self.drive = None
|
||||||
|
self.calls = 0
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(torch, name)
|
||||||
|
|
||||||
|
def mv(self, *args, **kwargs):
|
||||||
|
value = torch.mv(*args, **kwargs)
|
||||||
|
self.drive = value
|
||||||
|
self.calls += 1
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _up(value):
|
||||||
|
return np.nextafter(np.asarray(value, dtype=np.float64), np.inf)
|
||||||
|
|
||||||
|
|
||||||
|
def _add(a, b):
|
||||||
|
return _up(np.asarray(a, dtype=np.float64) + np.asarray(b, dtype=np.float64))
|
||||||
|
|
||||||
|
|
||||||
|
def _mul(a, b):
|
||||||
|
return _up(np.asarray(a, dtype=np.float64) * np.asarray(b, dtype=np.float64))
|
||||||
|
|
||||||
|
|
||||||
|
def _gamma(count, unit_roundoff):
|
||||||
|
require(count * unit_roundoff < 1, 'Gamma bound is undefined')
|
||||||
|
# Outward rounding on the division; the denominator is rounded downward.
|
||||||
|
numerator = _mul(count, unit_roundoff)
|
||||||
|
denominator = np.nextafter(1.0 - numerator, -np.inf)
|
||||||
|
return _up(numerator / denominator)
|
||||||
|
|
||||||
|
|
||||||
|
def _positive_dot_upper(state, matrix):
|
||||||
|
result = np.zeros(matrix.shape[1], np.float64)
|
||||||
|
for index in range(len(state)):
|
||||||
|
result = _add(result, _mul(state[index], matrix[index]))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _normal_or_zero(value, tiny):
|
||||||
|
value = np.asarray(value)
|
||||||
|
return bool(np.all((value == 0) | (value >= tiny)))
|
||||||
|
|
||||||
|
|
||||||
|
def _new_metric():
|
||||||
|
return {'max_abs_error': 0.0, 'sum_abs_error': 0.0, 'elements': 0,
|
||||||
|
'max_relative_error_nonzero_reference': 0.0, 'zero_reference_nonzero_actual': 0,
|
||||||
|
'max_error_bound': 0.0, 'max_bound_utilization': 0.0, 'bound_violations': 0}
|
||||||
|
|
||||||
|
|
||||||
|
def _accumulate(metric, actual, reference, bound):
|
||||||
|
error = np.abs(np.asarray(actual, np.float64) - reference)
|
||||||
|
error_upper = np.where(error == 0, 0.0, _up(error))
|
||||||
|
nonzero = reference != 0
|
||||||
|
ratio = np.divide(error, np.abs(reference), out=np.zeros_like(error), where=nonzero)
|
||||||
|
usage = np.divide(error_upper, bound, out=np.zeros_like(error), where=bound > 0)
|
||||||
|
metric['max_abs_error'] = max(metric['max_abs_error'], float(error.max(initial=0)))
|
||||||
|
metric['sum_abs_error'] += float(error.sum(dtype=np.float64))
|
||||||
|
metric['elements'] += error.size
|
||||||
|
metric['max_relative_error_nonzero_reference'] = max(metric['max_relative_error_nonzero_reference'], float(ratio.max(initial=0)))
|
||||||
|
metric['zero_reference_nonzero_actual'] += int(np.count_nonzero((~nonzero) & (error != 0)))
|
||||||
|
metric['max_error_bound'] = max(metric['max_error_bound'], float(np.max(bound, initial=0)))
|
||||||
|
metric['max_bound_utilization'] = max(metric['max_bound_utilization'], float(usage.max(initial=0)))
|
||||||
|
metric['bound_violations'] += int(np.count_nonzero(error_upper > bound))
|
||||||
|
|
||||||
|
|
||||||
|
def validate(gpu_case_dir, bundle_dir, out_json):
|
||||||
|
"""Validate one completed fixture; write one exclusive pure-JSON audit."""
|
||||||
|
gpu_case_dir, bundle_dir, out_json = Path(gpu_case_dir), Path(bundle_dir), Path(out_json)
|
||||||
|
require(not out_json.exists(), 'Refusing to overwrite an existing component audit')
|
||||||
|
report = {'pass_all': False, 'scope': 'Frozen APL component extraction and recorded-spike replay only',
|
||||||
|
'independent_cpu_closed_loop_oracle': False, 'brain_or_learning_parameters_changed': False,
|
||||||
|
'candidate_function_called': False, 'gpu_case_dir': str(gpu_case_dir), 'bundle_dir': str(bundle_dir)}
|
||||||
|
try:
|
||||||
|
require(digest(SOURCE) == SOURCE_SHA256, 'Frozen source changed before component validation')
|
||||||
|
require(torch.cuda.is_available() and torch.cuda.device_count() == 1 and
|
||||||
|
'4090' in torch.cuda.get_device_name(), 'Require the one declared RTX4090')
|
||||||
|
environment = {'torch': str(torch.__version__), 'numpy': np.__version__,
|
||||||
|
'gpu': torch.cuda.get_device_name(), 'cuda': torch.version.cuda,
|
||||||
|
'cuda_matmul_allow_tf32': torch.backends.cuda.matmul.allow_tf32,
|
||||||
|
'float32_matmul_precision': torch.get_float32_matmul_precision(),
|
||||||
|
'deterministic_algorithms': torch.are_deterministic_algorithms_enabled(),
|
||||||
|
'precision_flags_changed': False}
|
||||||
|
report['environment'] = environment
|
||||||
|
canonical_hashes = tuple(sorted((name, digest(path)) for name, path in _canonical_files().items()))
|
||||||
|
view, reconstructed, provenance, code = reconstruct(canonical_hashes, 'cuda:0')
|
||||||
|
bundle = {}
|
||||||
|
matrix_checks = {}
|
||||||
|
for name, (dtype, shape) in BUNDLE_ARRAYS.items():
|
||||||
|
value = np.load(bundle_dir/(name+'.npy'), mmap_mode='r', allow_pickle=False)
|
||||||
|
require(value.dtype == dtype and value.ndim == len(shape or (0,)) and
|
||||||
|
(shape is None or value.shape == shape), 'Bundle schema mismatch: '+name)
|
||||||
|
bundle[name] = value
|
||||||
|
matrix_checks[name] = bit_equal(value, reconstructed[name])
|
||||||
|
scales = json.loads((bundle_dir/'scales.json').read_text())
|
||||||
|
for name in ('input_scale', 'output_scale'):
|
||||||
|
matrix_checks[name] = struct.pack('<d', float(scales[name])) == struct.pack('<d', float(getattr(view, name)))
|
||||||
|
report['matrix_checks'] = matrix_checks
|
||||||
|
report['extracted_source'] = provenance
|
||||||
|
report['canonical_sha256'] = dict(canonical_hashes)
|
||||||
|
report['bundle_sha256'] = {name+'.npy': digest(bundle_dir/(name+'.npy')) for name in BUNDLE_ARRAYS}
|
||||||
|
report['bundle_sha256']['scales.json'] = digest(bundle_dir/'scales.json')
|
||||||
|
report['reconstructed_array_sha256'] = {name: array_hash(value) for name, value in reconstructed.items()}
|
||||||
|
bundle_provenance = json.loads((bundle_dir/'provenance.json').read_text())
|
||||||
|
require(Path(bundle_provenance['canonical_root']).resolve() == CANONICAL.resolve(),
|
||||||
|
'Bundle provenance names another canonical dataset')
|
||||||
|
report['bundle_sha256']['provenance.json'] = digest(bundle_dir/'provenance.json')
|
||||||
|
require(all(matrix_checks.values()), 'Bundle differs from the actual frozen initializer prefix')
|
||||||
|
|
||||||
|
traces = {name: np.load(gpu_case_dir/('apl-'+name+'.float32.npy'), mmap_mode='r', allow_pickle=False)
|
||||||
|
for name in ('drive', 'state', 'inhibition')}
|
||||||
|
steps = len(traces['state'])
|
||||||
|
require(steps > 0, 'Empty APL trajectory cannot pass')
|
||||||
|
for name, width in (('drive', A), ('state', A), ('inhibition', K)):
|
||||||
|
require(traces[name].dtype == np.float32 and traces[name].shape == (steps, width) and
|
||||||
|
bool(np.isfinite(traces[name]).all()) and bool(np.all(traces[name] >= 0)), 'Invalid APL trace: '+name)
|
||||||
|
summary = json.loads((gpu_case_dir/'summary.json').read_text())
|
||||||
|
require(summary.get('complete') is True and summary.get('pass_all') is True and
|
||||||
|
summary.get('steps') == steps and summary.get('completed_ticks') == steps,
|
||||||
|
'GPU fixture did not complete its internal execution checks')
|
||||||
|
with np.load(gpu_case_dir/'state.npz', allow_pickle=False) as archive:
|
||||||
|
event_step, event_node = archive['step'].copy(), archive['neuron_idx'].copy()
|
||||||
|
require(event_step.dtype == event_node.dtype == np.int32 and event_step.ndim == 1 and
|
||||||
|
event_step.shape == event_node.shape, 'Invalid sparse actual spike event schema')
|
||||||
|
require(bool(np.all((event_step >= 0) & (event_step < steps))) and
|
||||||
|
bool(np.all((event_node >= 0) & (event_node < N))), 'Sparse event outside its clock/identity range')
|
||||||
|
require(np.array_equal(np.lexsort((event_node, event_step)), np.arange(len(event_step))), 'Actual events not sorted')
|
||||||
|
keys = event_step.astype(np.int64)*N + event_node
|
||||||
|
require(len(keys) < 2 or bool(np.all(np.diff(keys) > 0)), 'Duplicate actual spikes')
|
||||||
|
boundaries = np.searchsorted(event_step, np.arange(steps + 1))
|
||||||
|
|
||||||
|
proxy = TorchObservationProxy()
|
||||||
|
# Reconstructed original matrices are already on the original GPU/dtype.
|
||||||
|
replay_rt = types.SimpleNamespace(spike_u8=torch.zeros(N, dtype=torch.uint8, device=view.device))
|
||||||
|
shadow = types.SimpleNamespace(input_gpu=view.input_gpu, output_gpu=view.output_gpu, rt=replay_rt, dt=.1)
|
||||||
|
scope = {'self': shadow, 'np': np, 'math': math, 'torch': proxy,
|
||||||
|
'apl_state': torch.zeros(A, dtype=torch.float32, device=view.device)}
|
||||||
|
decay_code, update_code, gain_code = code
|
||||||
|
exec(decay_code, scope)
|
||||||
|
decay32 = np.float32(scope['apl_decay'])
|
||||||
|
gain32 = np.float32(eval(gain_code, {'np': np}))
|
||||||
|
require(0 < decay32 < 1 and gain32 > 0, 'Invalid extracted positive APL constants')
|
||||||
|
exact = {name: True for name in traces}
|
||||||
|
first_difference = None
|
||||||
|
I64 = np.asarray(bundle['input_matrix'], np.float64)
|
||||||
|
O64 = np.asarray(bundle['output_matrix'], np.float64)
|
||||||
|
require(bool(np.all(I64 >= 0)) and bool(np.all(O64 >= 0)), 'Positive-sum theory requires nonnegative matrices')
|
||||||
|
d, q = float(decay32), float(gain32)
|
||||||
|
u32, u64 = 2.0**-24, 2.0**-53
|
||||||
|
gd32, gd64 = _gamma(N-1, u32), _gamma(N-1, u64)
|
||||||
|
g232, g264 = _gamma(2, u32), _gamma(2, u64)
|
||||||
|
gh32, gh64 = _gamma(2*A+1, u32), _gamma(2*A+1, u64)
|
||||||
|
state64 = np.zeros(A, np.float64)
|
||||||
|
e32 = np.zeros(A, np.float64)
|
||||||
|
e64 = np.zeros(A, np.float64)
|
||||||
|
previous32 = np.zeros(A, np.float64)
|
||||||
|
statistics = {name: _new_metric() for name in traces}
|
||||||
|
normal_arithmetic = _normal_or_zero(I64, np.finfo(np.float32).tiny) and _normal_or_zero(O64, np.finfo(np.float32).tiny)
|
||||||
|
max_active_terms = 0
|
||||||
|
with torch.no_grad():
|
||||||
|
for tick in range(steps):
|
||||||
|
fired = event_node[boundaries[tick]:boundaries[tick+1]]
|
||||||
|
replay_rt.spike_u8.zero_()
|
||||||
|
if len(fired):
|
||||||
|
replay_rt.spike_u8[torch.as_tensor(fired.astype(np.int64), device=view.device)] = 1
|
||||||
|
before_calls = proxy.calls
|
||||||
|
exec(update_code, scope)
|
||||||
|
require(proxy.calls == before_calls + 1, 'Original update did not issue exactly one mv')
|
||||||
|
actual = {'drive': proxy.drive.detach().cpu().numpy(),
|
||||||
|
'state': scope['apl_state'].detach().cpu().numpy(),
|
||||||
|
'inhibition': scope['inhibition'].detach().cpu().numpy()}
|
||||||
|
for name in traces:
|
||||||
|
same = bit_equal(actual[name], traces[name][tick])
|
||||||
|
exact[name] &= same
|
||||||
|
if not same and first_difference is None:
|
||||||
|
first_difference = {'tick': tick, 'field': name,
|
||||||
|
'max_abs_error': float(np.max(np.abs(actual[name].astype(np.float64)-traces[name][tick])))}
|
||||||
|
# Float64 reference is measurement only and never feeds either brain.
|
||||||
|
selected = I64[:, fired]
|
||||||
|
drive64 = selected.sum(axis=1, dtype=np.float64)
|
||||||
|
max_active_terms = max(max_active_terms, int(np.count_nonzero(selected, axis=1).max(initial=0)))
|
||||||
|
Dupper = _up(drive64 / np.nextafter(1.0-gd64, -np.inf))
|
||||||
|
drive_bound = _add(_mul(gd32, Dupper), _mul(gd64, Dupper))
|
||||||
|
state32 = traces['state'][tick].astype(np.float64)
|
||||||
|
normal_arithmetic &= _normal_or_zero(d*previous32, np.finfo(np.float32).tiny)
|
||||||
|
normal_arithmetic &= _normal_or_zero(O64*state32[:, None], np.finfo(np.float32).tiny)
|
||||||
|
e32 = _add(_mul(d, e32), _add(_mul(g232, _add(_mul(d, previous32), Dupper)),
|
||||||
|
_mul(1.0+u32, _mul(gd32, Dupper))))
|
||||||
|
e64 = _add(_mul(d, e64), _add(_mul(g264, _add(_mul(d, state64), Dupper)),
|
||||||
|
_mul(1.0+u64, _mul(gd64, Dupper))))
|
||||||
|
state64 = d*state64 + drive64
|
||||||
|
inhibition64 = np.matmul(state64, O64)*q
|
||||||
|
h32bound = _add(_mul(q, _positive_dot_upper(e32, O64)),
|
||||||
|
_mul(gh32, _mul(q, _positive_dot_upper(state32, O64))))
|
||||||
|
h64bound = _add(_mul(q, _positive_dot_upper(e64, O64)),
|
||||||
|
_mul(gh64, _mul(q, _positive_dot_upper(state64, O64))))
|
||||||
|
normal_arithmetic &= _normal_or_zero(q*np.matmul(state32, O64), np.finfo(np.float32).tiny)
|
||||||
|
_accumulate(statistics['drive'], traces['drive'][tick], drive64, drive_bound)
|
||||||
|
_accumulate(statistics['state'], traces['state'][tick], state64, _add(e32, e64))
|
||||||
|
_accumulate(statistics['inhibition'], traces['inhibition'][tick], inhibition64, _add(h32bound, h64bound))
|
||||||
|
previous32 = state32
|
||||||
|
for metric in statistics.values():
|
||||||
|
metric['mean_abs_error'] = metric.pop('sum_abs_error') / metric['elements']
|
||||||
|
theory_applicable = bool(normal_arithmetic and not environment['cuda_matmul_allow_tf32'] and
|
||||||
|
environment['float32_matmul_precision'] == 'highest')
|
||||||
|
report.update(steps=steps, actual_spike_events=len(event_step),
|
||||||
|
ast_replay_bitwise_exact=exact, first_ast_difference=first_difference,
|
||||||
|
value_units={'drive': 'legacy normalized-contact spike drive',
|
||||||
|
'state': 'legacy normalized-drive accumulator', 'inhibition': 'legacy mV'},
|
||||||
|
decay_f32_bits=f'{int(decay32.view(np.uint32)):08x}', gain_f32_bits=f'{int(gain32.view(np.uint32)):08x}',
|
||||||
|
float64_measurement=statistics,
|
||||||
|
theoretical_bound={'applicable': theory_applicable, 'normal_or_zero_arithmetic': bool(normal_arithmetic),
|
||||||
|
'gamma_definition': 'gamma_n=(n*u)/(1-n*u), upward-rounded; u32=2^-24,u64=2^-53',
|
||||||
|
'drive_n': N-1, 'max_observed_nonzero_drive_terms': max_active_terms,
|
||||||
|
'gamma_drive_f32': float(gd32), 'gamma_drive_f64': float(gd64),
|
||||||
|
'state_recurrence': 'E_p[t] <= d*E_p[t-1] + gamma_2,p*(d*abs(s_p[t-1])+D_upper) + (1+u_p)*gamma_(N-1),p*D_upper',
|
||||||
|
'output_bound': 'q*sum(B*E_p) + gamma_(2*A+1),p*q*sum(B*abs(s_p)); compare with E32+E64',
|
||||||
|
'assumptions': 'nonnegative f32 matrices, spikes exactly 0/1, fixed stored f32 decay/gain, normal finite RN binary32/64 operations; no reduced-precision matmul',
|
||||||
|
'bound_arithmetic': 'Each positive bound operation is rounded toward +infinity via nextafter; denominator toward -infinity',
|
||||||
|
'tolerance_fitted_to_observed_error': False,
|
||||||
|
'f64_values_used_to_drive_brain': False,
|
||||||
|
'no_cpu_gpu_bitwise_expectation_for_f64_measurement': True},
|
||||||
|
input_sha256={name: digest(gpu_case_dir/name) for name in
|
||||||
|
('state.npz', 'summary.json', 'apl-drive.float32.npy', 'apl-state.float32.npy', 'apl-inhibition.float32.npy')})
|
||||||
|
report['pass_all'] = bool(all(matrix_checks.values()) and all(exact.values()) and theory_applicable and
|
||||||
|
all(value['bound_violations'] == 0 for value in statistics.values()))
|
||||||
|
report['limitations'] = [
|
||||||
|
'AST shadow and candidate use the same original Torch/CUDA primitives; this validates preserved component semantics, not an independent CPU whole-brain oracle.',
|
||||||
|
'Float64 is a non-feedback mathematical measurement with explicit gamma error bounds, not replacement APL dynamics.',
|
||||||
|
'Replay uses the recorded actual spike train; it does not establish equivalence for untested closed-loop inputs.',
|
||||||
|
'The N-1 positive-sum bound is deliberately conservative; passing it does not prove physiological validity or learning.']
|
||||||
|
save(out_json, report)
|
||||||
|
return report
|
||||||
|
except Exception as error:
|
||||||
|
report['error'] = {'type': type(error).__name__, 'message': str(error)}
|
||||||
|
if not out_json.exists():
|
||||||
|
save(out_json, report)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('gpu_case_dir', type=Path)
|
||||||
|
parser.add_argument('bundle_dir', type=Path)
|
||||||
|
parser.add_argument('out_json', type=Path)
|
||||||
|
args = parser.parse_args()
|
||||||
|
result = validate(args.gpu_case_dir, args.bundle_dir, args.out_json)
|
||||||
|
print(json.dumps({'pass_all': result['pass_all'], 'steps': result['steps']}), flush=True)
|
||||||
|
if not result['pass_all']:
|
||||||
|
raise SystemExit(1)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
"""Run old reference unchanged, writing only new experiment output."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import yaml
|
||||||
|
from context import ROOT,EXP,CFG,save,check
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
check();assert not (EXP/'regression/frozen-five.json').exists()
|
||||||
|
rtpath=ROOT/'models/male-cns-lif/deterministic-runtime-v2';pc=yaml.safe_load((rtpath/'phase4p.yaml').read_text())
|
||||||
|
os.environ['CUDA_VISIBLE_DEVICES']=CFG['gpu_uuid'];os.environ['CUDA_HOME']='/usr/local/cuda'
|
||||||
|
os.environ['PATH']=str(ROOT/'models/male-cns-lif/.venv/bin')+':/usr/local/cuda/bin:'+os.environ['PATH']
|
||||||
|
os.environ['MAX_JOBS']='2';os.environ['TORCH_CUDA_ARCH_LIST']='8.9'
|
||||||
|
sys.path.insert(0,str(ROOT/'models/male-cns-lif/terminal-scope-diagnostic-v1'))
|
||||||
|
from diagnostic import queues
|
||||||
|
queues();sys.path.insert(0,str(ROOT/'models/male-cns-lif'));sys.path.insert(0,str(rtpath))
|
||||||
|
import torch,phase4p
|
||||||
|
assert torch.cuda.mem_get_info()[0]>2*1024**3
|
||||||
|
torch.cuda.reset_peak_memory_stats();t0=time.perf_counter();rt=phase4p.CanonicalRuntime(pc,rtpath,EXP);rows=[]
|
||||||
|
for spec in pc['reference_trials']:
|
||||||
|
queues();base=ROOT/'experiments/phase4p-deterministic-runtime/phase4c-v2/reference'/spec['name']
|
||||||
|
ev=pd.read_parquet(base/'spike-events.parquet')
|
||||||
|
ref=dict(step=ev.step.to_numpy(),neuron_idx=ev.neuron_idx.to_numpy(),counts=np.load(base/'per-neuron-spike-counts.int32.npy'),v=np.load(base/'final-voltage.float32.npy'),g=np.load(base/'final-g.float32.npy'))
|
||||||
|
result=rt.run(np.flatnonzero(rt.pops[spec['population']]),spec['rate_hz'],spec['seed'],spec['duration_ms'])
|
||||||
|
row=dict(trial=spec['name'],exact={k:bool(np.array_equal(v,result[k])) for k,v in ref.items()},wall_seconds=result['metrics']['wall_seconds'])
|
||||||
|
rows.append(row);print(row,flush=True)
|
||||||
|
save(EXP/'regression/frozen-five.json',dict(pass_all=all(all(r['exact'].values()) for r in rows),trials=rows,
|
||||||
|
wall_seconds=time.perf_counter()-t0,peak_allocated_vram=int(torch.cuda.max_memory_allocated()),oracle='old frozen deterministic-v2 only'))
|
||||||
|
assert all(all(r['exact'].values()) for r in rows)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# Phase4AG: author LIF + frozen legacy graded APL
|
||||||
|
|
||||||
|
Execution revision r2: the first registered v1 attempt stopped before the first
|
||||||
|
Brian tick because resolving the science-venv Python symlink launched system
|
||||||
|
Python without NumPy. All v1 files and partial outputs are preserved separately.
|
||||||
|
This revision retains the declared venv invocation path. It does not change any
|
||||||
|
equation, arithmetic, mask, stimulus, gate, parameter or choice of trial.
|
||||||
|
The complete original protocol is rerun from fresh state; no failed trial is
|
||||||
|
overwritten or omitted, and the first version cannot be claimed numerical PASS.
|
||||||
|
|
||||||
|
Authorized independent hypothesis branch. All old source, raw connectome, signs,
|
||||||
|
W_syn, APL calibration, eligibility-v2 and 14,232-edge mask remain read-only.
|
||||||
|
No learning, gain/threshold changes, new edges, top-K, heldout activity, game or RL.
|
||||||
|
|
||||||
|
Author code provenance is the already archived MIT-licensed
|
||||||
|
https://github.com/philshiu/Drosophila_brain_model at
|
||||||
|
91bdd1e7dcf193f3e7ca5a8933497fcef63b7960; original model.py SHA-256
|
||||||
|
fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e.
|
||||||
|
Associated paper: https://www.nature.com/articles/s41586-024-07763-9.
|
||||||
|
This new MaleCNS/APL combination is not a strict reproduction of that model.
|
||||||
|
|
||||||
|
The declared combination is author float64 LIF plus the exact old float32 graded
|
||||||
|
APL operator after synapses/resets at end. All 5,845 original APL fast out-edges
|
||||||
|
are zeroed only in the effective in-memory model, as in the legacy overlay.
|
||||||
|
Only KC receives graded replacement; known 1,212 non-KC edges remain unreplaced.
|
||||||
|
This existing scope limitation is not silently repaired in a compatibility test.
|
||||||
|
|
||||||
|
Use the original full normalized I[2,166700]/O[2,4064] float32 bytes and original
|
||||||
|
normalizers, even for induced real subgraphs. APL reads actual binary spikes,
|
||||||
|
never requests, and keeps independent float32 state. Preserve unfused operations:
|
||||||
|
state.mul_(float(f32(exp(-.1/20)))).add_(torch.mv(I, spikes_f32));
|
||||||
|
h32=torch.matmul(state,O)*f32(.01). Promote h32 to float64, multiply by float64
|
||||||
|
.001, then separately subtract from SI g. Do not alter TF32/default CuBLAS flags;
|
||||||
|
record them. No added APL delay, drive dt/tau scaling, truncation or clipping.
|
||||||
|
|
||||||
|
APL writes KC g unconditionally after author reset, including refractory KC.
|
||||||
|
Author g integration is frozen during refractory; therefore negative overlay g
|
||||||
|
may accumulate and differs from old dynamics. This is an explicit hypothesis,
|
||||||
|
not an assertion of original author or measured physiology. Guarded writes or
|
||||||
|
reset-before/after changes would be different hypotheses, not fixes to this one.
|
||||||
|
|
||||||
|
Eight fixed metadata/connectivity-selected fixtures cover zero/reset, real PN/KC
|
||||||
|
drive, current actual event feedback, duplicate natural/request event, 18-step
|
||||||
|
arrival vs22-step refractory boundary, full fast APL mask, non-KC scope and mixed
|
||||||
|
precision/high fan-in. No choice is made from runtime responses. Each GPU case
|
||||||
|
has3 independent fresh runs. A Brian2 author oracle starts from its own state,
|
||||||
|
computes its own actual spikes, and uses an isolated standard-I/O legacy-APL
|
||||||
|
worker with independent state. No candidate inhibition trace is fed into Brian.
|
||||||
|
All tick states, events, requests, queue order/guard, APL drive/state/h must agree
|
||||||
|
exactly. The APL component is shared, so this is NOT a fully independent CPU
|
||||||
|
oracle. Independently reconstruct old matrices using frozen initializer AST,
|
||||||
|
replay actual events through original update AST, require exact component bytes;
|
||||||
|
also quantify an independent float64 positive-sum arithmetic error bound. It is
|
||||||
|
not a replacement for exact legacy equivalence. No arithmetic bound is adjusted.
|
||||||
|
|
||||||
|
Only after all fixture gates pass, run two predeclared full-graph probes: first
|
||||||
|
old calibration odor, first original seed, both encoder modes. Compare each with
|
||||||
|
the independently running Brian + isolated APL worker. Save state hashes and sparse
|
||||||
|
events, not a time-by-all-neurons dense spike matrix. If a numerical gate fails,
|
||||||
|
stop CAL; keep diagnostic evidence and do not widen tolerance.
|
||||||
|
|
||||||
|
Then run the complete original6 CAL odors ×5 original seeds ×2 original modes,
|
||||||
|
100ms per run. Retain the ORIGINAL12-odor median for matched-energy encoding,
|
||||||
|
original pn_drive target/RNG column order, original evaluation seeds51101..51105.
|
||||||
|
Save Poisson requests before any trajectory. Only calibration dynamic cases are
|
||||||
|
used; formal A/B and heldout remain unrun. Repeat first seed for every odor/mode.
|
||||||
|
No per-odor pulse, amplitude, timing or threshold search. No learning.
|
||||||
|
|
||||||
|
Recompute the full original4L representation criteria on CAL only: mean KC active
|
||||||
|
fraction .03..09, min>0, max<.5, same-odor Jaccard>different, between Euclidean>
|
||||||
|
within, >=3 pairs whose mean between exceeds THAT PAIR's pooled within distances,
|
||||||
|
both modes. Add finiteness and exact repeat requirements. CAL PASS does not imply
|
||||||
|
heldout generalization, timing/credit specificity, memory or learning usability.
|
||||||
|
If CAL fails stop promotion and report it, not a least-bad candidate.
|
||||||
|
|
||||||
|
Before/after verify SHA-256 of all original230239 files and AA--AF seals; rerun original five
|
||||||
|
deterministic reference trials to new output. Archive code/env/source SHA,
|
||||||
|
matrices/norms/masks/identities, requests and all outputs. No published candidate.
|
||||||
|
|
||||||
|
Technical references (queried2026-09-30): Brian2 2.5.1 refractory documentation
|
||||||
|
https://brian2.readthedocs.io/en/2.5.1/user/refractoriness.html (actual generated code
|
||||||
|
remains authoritative); PyTorch numerical accuracy notes
|
||||||
|
https://docs.pytorch.org/docs/2.14/notes/numerical_accuracy.html (cross-backend
|
||||||
|
floating operations are not assumed bitwise equivalent).
|
||||||
@@ -0,0 +1,396 @@
|
|||||||
|
"""Complete original Phase 4L representation metrics on fixed CAL inputs only.
|
||||||
|
|
||||||
|
No simulation, fitting, heldout trajectory access, or candidate generation is
|
||||||
|
performed here. The original 4L pair-specific within-odor baseline is retained;
|
||||||
|
the weaker Phase 4P r4 aggregate gate is deliberately not used.
|
||||||
|
"""
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import itertools
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
STATE_DTYPES = {"step": np.int32, "neuron_idx": np.int32, "counts": np.int32,
|
||||||
|
"v": np.float64, "g": np.float64, "ref": np.int32}
|
||||||
|
REQUEST_FIELDS = ("tick", "neuron_idx", "attempted", "accepted", "rejected")
|
||||||
|
APL_FILES = {"apl-drive.float32.npy": 2, "apl-state.float32.npy": 2,
|
||||||
|
"apl-inhibition.float32.npy": 4064}
|
||||||
|
ORIGINAL_CAL_IDS = {
|
||||||
|
"OMSUIQOIVADKIM-RXMQYKEDSA-N", "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"QNVRIHYSUZMSGM-ZCFIWIBFSA-N", "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"XHIUFYZDQBSEMF-UHFFFAOYSA-N", "OMSUIQOIVADKIM-YFKPBYRVSA-N"}
|
||||||
|
ORIGINAL_MODES = ("physiological", "matched_energy")
|
||||||
|
ORIGINAL_SEEDS = (51101, 51102, 51103, 51104, 51105)
|
||||||
|
HEX_SHA = re.compile(r"[0-9a-f]{64}\Z")
|
||||||
|
_DEFAULT_OUTPUT = object()
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def read_json(path):
|
||||||
|
with Path(path).open(encoding="utf-8") as stream:
|
||||||
|
return json.load(stream)
|
||||||
|
|
||||||
|
|
||||||
|
def file_hash(path):
|
||||||
|
digest = hashlib.sha256()
|
||||||
|
with Path(path).open("rb") as stream:
|
||||||
|
for block in iter(lambda: stream.read(8 << 20), b""):
|
||||||
|
digest.update(block)
|
||||||
|
return digest.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def raw_hash(value):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def arrays_bitwise_equal(first, second):
|
||||||
|
"""Unlike array_equal, also reject different dtypes and signed-zero bits."""
|
||||||
|
return bool(first.dtype == second.dtype and first.shape == second.shape and
|
||||||
|
np.array_equal(np.ascontiguousarray(first).view(np.uint8),
|
||||||
|
np.ascontiguousarray(second).view(np.uint8)))
|
||||||
|
|
||||||
|
|
||||||
|
def pair_metrics(a, b):
|
||||||
|
"""Exact definitions copied from phase4i.pair_metrics/safe_corr/cosine."""
|
||||||
|
x, y = a.astype(np.float64), b.astype(np.float64)
|
||||||
|
aa, bb = a > 0, b > 0
|
||||||
|
union = int(np.count_nonzero(aa | bb))
|
||||||
|
intersection = int(np.count_nonzero(aa & bb))
|
||||||
|
denominator = float(np.linalg.norm(x) * np.linalg.norm(y))
|
||||||
|
cosine = 1.0 if denominator == 0 and np.array_equal(x, y) else (
|
||||||
|
0.0 if denominator == 0 else float(np.dot(x, y) / denominator))
|
||||||
|
correlation = (1.0 if np.array_equal(x, y) else 0.0) if np.std(x) == 0 or np.std(y) == 0 else float(np.corrcoef(x, y)[0, 1])
|
||||||
|
return {"active_intersection": intersection, "active_union": union,
|
||||||
|
"active_jaccard": 1.0 if union == 0 else float(intersection / union),
|
||||||
|
"cosine_similarity": cosine, "correlation": correlation,
|
||||||
|
"euclidean_distance": float(np.linalg.norm(x - y))}
|
||||||
|
|
||||||
|
|
||||||
|
def evaluate_gates(summary, gates):
|
||||||
|
"""Each conjunct in original phase4l.py:239, kept visible for audit."""
|
||||||
|
return {
|
||||||
|
"mean_sparsity_in_closed_interval": bool(float(gates["sparse_min_fraction"]) <=
|
||||||
|
summary["KC_active_fraction_mean"] <= float(gates["sparse_max_fraction"])),
|
||||||
|
"maximum_strictly_below_half": bool(summary["KC_active_fraction_max"] < 0.5),
|
||||||
|
"minimum_strictly_positive": bool(summary["KC_active_fraction_min"] > 0),
|
||||||
|
"same_jaccard_gt_different": bool(summary["same_odor_jaccard_mean"] > summary["different_odor_jaccard_mean"]),
|
||||||
|
"different_euclidean_gt_same": bool(summary["different_odor_euclidean_mean"] > summary["same_odor_euclidean_mean"]),
|
||||||
|
"at_least_original_pair_count": bool(summary["pairwise_separation_pass_count"] >= int(gates["minimum_separable_odor_pairs"]))}
|
||||||
|
|
||||||
|
|
||||||
|
def sample_cv(values):
|
||||||
|
"""Original pandas Series.std uses ddof=1. Undefined diagnostic -> null."""
|
||||||
|
values = np.asarray(values, dtype=np.float64)
|
||||||
|
mean = float(values.mean())
|
||||||
|
return None if mean == 0 else float(values.std(ddof=1) / mean)
|
||||||
|
|
||||||
|
|
||||||
|
def summarize_mode(mode, odor_ids, seeds, runs, gates):
|
||||||
|
within, within_j, between, between_j, between_cos, between_corr = [], [], [], [], [], []
|
||||||
|
pairs = []
|
||||||
|
for odor in odor_ids:
|
||||||
|
arrays = [runs[(mode, odor, seed)]["kc_counts"] for seed in seeds]
|
||||||
|
for first, second in itertools.combinations(arrays, 2):
|
||||||
|
metric = pair_metrics(first, second)
|
||||||
|
within.append(metric["euclidean_distance"])
|
||||||
|
within_j.append(metric["active_jaccard"])
|
||||||
|
for first_odor, second_odor in itertools.combinations(odor_ids, 2):
|
||||||
|
distances = []
|
||||||
|
for seed in seeds:
|
||||||
|
metric = pair_metrics(runs[(mode, first_odor, seed)]["kc_counts"],
|
||||||
|
runs[(mode, second_odor, seed)]["kc_counts"])
|
||||||
|
distances.append(metric["euclidean_distance"])
|
||||||
|
between.append(metric["euclidean_distance"])
|
||||||
|
between_j.append(metric["active_jaccard"])
|
||||||
|
between_cos.append(metric["cosine_similarity"])
|
||||||
|
between_corr.append(metric["correlation"])
|
||||||
|
pair_within = []
|
||||||
|
for odor in (first_odor, second_odor):
|
||||||
|
arrays = [runs[(mode, odor, seed)]["kc_counts"] for seed in seeds]
|
||||||
|
pair_within.extend(pair_metrics(first, second)["euclidean_distance"]
|
||||||
|
for first, second in itertools.combinations(arrays, 2))
|
||||||
|
cross_mean, within_mean = float(np.mean(distances)), float(np.mean(pair_within))
|
||||||
|
pairs.append({"odor_id_a": first_odor, "odor_id_b": second_odor,
|
||||||
|
"between_same_seed_mean": cross_mean, "within_this_pair_mean": within_mean,
|
||||||
|
"between_distance_count": len(distances), "within_distance_count": len(pair_within),
|
||||||
|
"gate": bool(cross_mean > within_mean)})
|
||||||
|
selected = [runs[(mode, odor, seed)] for odor in odor_ids for seed in seeds]
|
||||||
|
fractions = [int(np.count_nonzero(run["kc_counts"])) / len(run["kc_counts"]) for run in selected]
|
||||||
|
summary = {"KC_active_fraction_mean": float(np.mean(fractions)),
|
||||||
|
"KC_active_fraction_min": float(np.min(fractions)), "KC_active_fraction_max": float(np.max(fractions)),
|
||||||
|
"same_odor_jaccard_mean": float(np.mean(within_j)),
|
||||||
|
"different_odor_jaccard_mean": float(np.mean(between_j)),
|
||||||
|
"same_odor_euclidean_mean": float(np.mean(within)),
|
||||||
|
"different_odor_euclidean_mean": float(np.mean(between)),
|
||||||
|
"different_odor_cosine_mean": float(np.mean(between_cos)),
|
||||||
|
"different_odor_correlation_mean": float(np.mean(between_corr)),
|
||||||
|
"within_variance": float(np.var(within)), "between_distance_mean": float(np.mean(between)),
|
||||||
|
"pairwise_separation_pass_count": sum(row["gate"] for row in pairs), "pair_count": len(pairs),
|
||||||
|
"expected_event_count_cv": sample_cv([run["expected_external_events"] for run in selected]),
|
||||||
|
"actual_event_count_cv": sample_cv([run["external_events"] for run in selected]),
|
||||||
|
"within_distance_count": len(within), "between_distance_count": len(between),
|
||||||
|
"pairwise_baseline": "Each pair's two odors: 10+10 within-seed distances; never pooled across all odors",
|
||||||
|
"pairs": pairs}
|
||||||
|
summary["conditions"] = evaluate_gates(summary, gates)
|
||||||
|
summary["gate"] = bool(all(summary["conditions"].values()))
|
||||||
|
return summary
|
||||||
|
|
||||||
|
|
||||||
|
def validate_state(state, neurons, steps):
|
||||||
|
require(set(state) == set(STATE_DTYPES), "state.npz must have exactly the six declared arrays")
|
||||||
|
for name, dtype in STATE_DTYPES.items():
|
||||||
|
value = state[name]
|
||||||
|
require(value.dtype == dtype and value.ndim == 1, "Invalid state dtype/rank: " + name)
|
||||||
|
require(bool(np.isfinite(value).all()), "Nonfinite state: " + name)
|
||||||
|
if name not in ("step", "neuron_idx"):
|
||||||
|
require(value.shape == (neurons,), "Invalid state length: " + name)
|
||||||
|
ticks, nodes = state["step"], state["neuron_idx"]
|
||||||
|
require(ticks.shape == nodes.shape and bool(np.all((ticks >= 0) & (ticks < steps))) and
|
||||||
|
bool(np.all((nodes >= 0) & (nodes < neurons))), "Invalid sparse event indices")
|
||||||
|
keys = ticks.astype(np.int64) * neurons + nodes
|
||||||
|
require(bool(np.all(np.diff(keys) > 0)), "Sparse events not sorted unique by tick/global neuron")
|
||||||
|
require(np.array_equal(np.bincount(nodes, minlength=neurons), state["counts"]), "Counts disagree with sparse events")
|
||||||
|
require(bool(np.all((state["ref"] >= 0) & (state["ref"] <= 22))), "Final refractory outside frozen range")
|
||||||
|
return keys
|
||||||
|
|
||||||
|
|
||||||
|
def read_jsonl(path, steps, kind):
|
||||||
|
with Path(path).open(encoding="utf-8") as source:
|
||||||
|
rows = [json.loads(line) for line in source if line.strip()]
|
||||||
|
require(len(rows) == steps and [row.get("tick") for row in rows] == list(range(steps)),
|
||||||
|
"Missing/duplicate/reordered ticks in " + kind)
|
||||||
|
for row in rows:
|
||||||
|
names = ("v_sha256", "g_sha256", "ref_sha256") if kind == "state hashes" else (
|
||||||
|
"ordered_edge_sha256", "accepted_mask_sha256", "joint_sha256")
|
||||||
|
for name in names:
|
||||||
|
require(isinstance(row.get(name), str) and HEX_SHA.fullmatch(row[name]), "Invalid SHA256 in " + kind)
|
||||||
|
if kind == "queue":
|
||||||
|
require(type(row.get("count")) is int and type(row.get("accepted_count")) is int and
|
||||||
|
0 <= row["accepted_count"] <= row["count"], "Invalid queue counts")
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def read_trial(output, case, spec, kc_globals, neurons, edges):
|
||||||
|
summary = read_json(output / "summary.json")
|
||||||
|
steps = spec["steps"]
|
||||||
|
require(summary.get("complete") is True and summary.get("pass_all") is True and
|
||||||
|
summary.get("all_finite") is True and summary.get("steps") == steps and
|
||||||
|
summary.get("completed_ticks") == steps and summary.get("nodes") == neurons and
|
||||||
|
summary.get("edges") == edges and summary.get("precision") == "float64" and
|
||||||
|
summary.get("apl_precision") == "float32" and summary.get("case") == spec["name"] and
|
||||||
|
summary.get("record_history") is False and summary.get("learning") is False,
|
||||||
|
"Incomplete/failed/wrong-scope GPU summary")
|
||||||
|
with np.load(output / "state.npz", allow_pickle=False) as source:
|
||||||
|
state = {name: source[name].copy() for name in source.files}
|
||||||
|
event_keys = validate_state(state, neurons, steps)
|
||||||
|
hashes = read_jsonl(output / "tick-state-hashes.jsonl", steps, "state hashes")
|
||||||
|
for name in ("v", "g", "ref"):
|
||||||
|
require(hashes[-1][name + "_sha256"] == raw_hash(state[name]), "Final state does not match last tick hash: " + name)
|
||||||
|
queues = read_jsonl(output / "queue.jsonl", steps, "queue")
|
||||||
|
apl = {}
|
||||||
|
for name, width in APL_FILES.items():
|
||||||
|
value = np.load(output / name, mmap_mode="r", allow_pickle=False)
|
||||||
|
require(value.dtype == np.float32 and value.shape == (steps, width) and
|
||||||
|
bool(np.isfinite(value).all()) and bool(np.all(value >= 0)), "Invalid full APL trace: " + name)
|
||||||
|
apl[name] = value
|
||||||
|
with (output / "requests.csv").open(encoding="utf-8", newline="") as source:
|
||||||
|
reader = csv.DictReader(source)
|
||||||
|
require(tuple(reader.fieldnames or ()) == REQUEST_FIELDS, "Request CSV schema mismatch")
|
||||||
|
request_rows = [{name: int(row[name]) for name in REQUEST_FIELDS} for row in reader]
|
||||||
|
with np.load(case / "requests.npz", allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == {"tick", "neuron_idx"}, "Input request schema mismatch")
|
||||||
|
expected_ticks, expected_nodes = source["tick"], source["neuron_idx"]
|
||||||
|
require(expected_ticks.dtype == np.int32 and expected_nodes.dtype == np.int32 and
|
||||||
|
expected_ticks.ndim == 1 and expected_ticks.shape == expected_nodes.shape,
|
||||||
|
"Input request dtype/shape mismatch")
|
||||||
|
require(len(request_rows) == len(expected_ticks), "Requested event coverage mismatch")
|
||||||
|
require([row["tick"] for row in request_rows] == expected_ticks.tolist() and
|
||||||
|
[row["neuron_idx"] for row in request_rows] == expected_nodes.tolist(), "Requests differ from frozen input")
|
||||||
|
require(all(row["attempted"] == 1 and row["accepted"] in (0, 1) and
|
||||||
|
row["rejected"] == 1 - row["accepted"] for row in request_rows), "Invalid request acceptance bookkeeping")
|
||||||
|
requested_keys = expected_ticks.astype(np.int64) * neurons + expected_nodes
|
||||||
|
require(bool(np.all(np.diff(requested_keys) > 0)) and bool(np.all((expected_ticks >= 0) & (expected_ticks < steps))) and
|
||||||
|
bool(np.all((expected_nodes >= 0) & (expected_nodes < neurons))), "Input requests not sorted unique/in range")
|
||||||
|
actual_accepted = np.array([row["accepted"] for row in request_rows], dtype=np.uint8)
|
||||||
|
require(np.array_equal(np.isin(requested_keys, event_keys, assume_unique=True), actual_accepted.astype(bool)),
|
||||||
|
"Request accepted/rejected values disagree with actual spikes")
|
||||||
|
accepted = int(actual_accepted.sum())
|
||||||
|
require(summary.get("requested") == len(request_rows) and summary.get("accepted_requests") == accepted and
|
||||||
|
summary.get("rejected_requests") == len(request_rows) - accepted and
|
||||||
|
summary.get("total_spikes") == len(state["step"]), "Summary counts disagree with raw output")
|
||||||
|
component = read_json(output / "apl-component.json")
|
||||||
|
require(component.get("ok") is True and component.get("n_neurons") == neurons and
|
||||||
|
component.get("n_kc") == len(kc_globals) and component.get("n_apl") == 2 and
|
||||||
|
component.get("dt_ms") == .1 and summary.get("apl_component") == component,
|
||||||
|
"APL component provenance mismatch")
|
||||||
|
bundle = Path(spec["apl_bundle_dir"])
|
||||||
|
require(component.get("files_sha256") == {name: file_hash(bundle / name) for name in
|
||||||
|
("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")}, "APL bundle hashes changed")
|
||||||
|
inputs = summary.get("input_sha256", {})
|
||||||
|
require(inputs.get("spec.json") == file_hash(case / "spec.json") and
|
||||||
|
inputs.get("requests.npz") == file_hash(case / "requests.npz"), "Case input provenance mismatch")
|
||||||
|
kc_counts = state["counts"][kc_globals].copy()
|
||||||
|
kc_event_mask = np.isin(state["neuron_idx"], kc_globals)
|
||||||
|
record = {"case": spec["name"], "mode": spec["mode"], "odor_id": spec["odor_id"],
|
||||||
|
"odor_name": spec["odor_name"], "seed": spec["seed"], "split": "calibration",
|
||||||
|
"KC_active": int(np.count_nonzero(kc_counts)), "KC_active_fraction": float(np.count_nonzero(kc_counts) / len(kc_globals)),
|
||||||
|
"KC_spikes": int(kc_counts.sum()), "KC_first_latency_ms":
|
||||||
|
float(state["step"][kc_event_mask][0] * .1) if bool(np.any(kc_event_mask)) else None,
|
||||||
|
"external_events": accepted, "expected_external_events": float(spec["expected_external_events"]),
|
||||||
|
"total_PN_rate_hz": float(spec["rate_sum_hz"]), "finite": True,
|
||||||
|
"total_spikes": len(state["step"]), "requested": len(request_rows)}
|
||||||
|
require(np.isfinite(record["expected_external_events"]) and record["expected_external_events"] > 0,
|
||||||
|
"CAL expected external events must be finite and positive")
|
||||||
|
return {"state": state, "hashes": hashes, "queues": queues, "apl": apl,
|
||||||
|
"requests": request_rows, "component": component, "kc_counts": kc_counts,
|
||||||
|
"expected_external_events": record["expected_external_events"], "external_events": accepted,
|
||||||
|
"record": record, "output": output}
|
||||||
|
|
||||||
|
|
||||||
|
def exact_repeat(first, repeat):
|
||||||
|
checks = {"state/" + name: arrays_bitwise_equal(first["state"][name], repeat["state"][name]) for name in STATE_DTYPES}
|
||||||
|
checks.update({name: arrays_bitwise_equal(first["apl"][name], repeat["apl"][name]) for name in APL_FILES})
|
||||||
|
checks.update(tick_state_hashes=first["hashes"] == repeat["hashes"],
|
||||||
|
queues=first["queues"] == repeat["queues"], requests=first["requests"] == repeat["requests"],
|
||||||
|
apl_component=first["component"] == repeat["component"])
|
||||||
|
return {"pass_all": bool(all(checks.values())), "checks": checks,
|
||||||
|
"scope": "All six state arrays, every tick all-neuron hashes, APL raw float32 traces, queues, requests and APL environment"}
|
||||||
|
|
||||||
|
|
||||||
|
def validate_inventory(records, cfg):
|
||||||
|
require(tuple(cfg["calibration"]["modes"]) == ORIGINAL_MODES and
|
||||||
|
tuple(cfg["calibration"]["seeds"]) == ORIGINAL_SEEDS and
|
||||||
|
cfg["calibration"]["duration_ms"] == 100.0 and cfg["calibration"]["odor_count"] == 6 and
|
||||||
|
cfg["calibration"]["split"] == "calibration" and
|
||||||
|
cfg["calibration"]["repeat_first_seed_each_odor"] is True, "Frozen CAL design changed")
|
||||||
|
gates = cfg["gates"]
|
||||||
|
require(gates["sparse_min_fraction"] == .03 and gates["sparse_max_fraction"] == .09 and
|
||||||
|
gates["minimum_separable_odor_pairs"] == 3 and gates["max_fraction_strict"] == .5 and
|
||||||
|
gates["min_fraction_strict"] == 0 and all(gates[key] is True for key in
|
||||||
|
("same_jaccard_gt_between", "between_euclidean_gt_within", "both_modes_required", "finite_required", "repeat_exact_required")),
|
||||||
|
"Original representation gates or additional integrity gates changed")
|
||||||
|
expected = {(mode, index, seed) for mode in ORIGINAL_MODES for index in range(6) for seed in ORIGINAL_SEEDS}
|
||||||
|
require(len(records) == 60 and {(row["mode"], row["odor_index"], row["seed"]) for row in records} == expected,
|
||||||
|
"CAL inventory must cover exactly 2 modes x 6 odors x 5 seeds")
|
||||||
|
odors = []
|
||||||
|
for index in range(6):
|
||||||
|
ids = {row["odor_id"] for row in records if row["odor_index"] == index}
|
||||||
|
require(len(ids) == 1, "Odor identity changes across seeds/modes")
|
||||||
|
odors.append(next(iter(ids)))
|
||||||
|
require(set(odors) == ORIGINAL_CAL_IDS, "CAL identities differ from the original frozen six")
|
||||||
|
for row in records:
|
||||||
|
require(row["name"] == f"cal-{row['mode']}-{row['odor_index']:02d}-s{row['seed']}", "Unexpected CAL case name")
|
||||||
|
return odors
|
||||||
|
|
||||||
|
|
||||||
|
def summarize(out_json=_DEFAULT_OUTPUT):
|
||||||
|
"""Recompute; default writes exclusively, out_json=None is strictly read-only."""
|
||||||
|
from context import EXP, ROOT, CFG, check
|
||||||
|
target = EXP / "calibration/summary.json" if out_json is _DEFAULT_OUTPUT else (
|
||||||
|
None if out_json is None else Path(out_json))
|
||||||
|
require(target is None or not target.exists(), "Refusing existing calibration summary")
|
||||||
|
failures, runs, run_records, repeats, provenance = [], {}, [], [], []
|
||||||
|
modes, odors = {}, []
|
||||||
|
prerequisites_ok = False
|
||||||
|
encoder = None
|
||||||
|
records = []
|
||||||
|
try:
|
||||||
|
check()
|
||||||
|
records = read_json(EXP / "protocol/calibration-cases.json")
|
||||||
|
odors = validate_inventory(records, CFG)
|
||||||
|
encoder = read_json(EXP / "protocol/encoder-audit.json")
|
||||||
|
require(encoder["panel_count"] == 12 and encoder["cal_count"] == 6 and
|
||||||
|
encoder["seeds"] == list(ORIGINAL_SEEDS) and encoder["requested_before_any_dynamics"] is True and
|
||||||
|
encoder["formal_AB_run"] is False and encoder["heldout_run"] is False, "Invalid frozen encoder scope")
|
||||||
|
# Only static original-panel metadata is read, never heldout trajectories.
|
||||||
|
import pandas as pd
|
||||||
|
original = pd.read_parquet(ROOT / "experiments/phase4l-olfactory-grounding/odor-encoder/frozen-odor-panel.parquet")
|
||||||
|
require(len(original) == 12 and set(original[original.split == "calibration"].odor_id) == ORIGINAL_CAL_IDS,
|
||||||
|
"Original static panel identity mismatch")
|
||||||
|
require(float(np.median(original.mapped_response_sum)) == encoder["median_mapped_response_sum"],
|
||||||
|
"Matched-energy reference is not the original frozen 12-panel median")
|
||||||
|
kc_globals = np.load(EXP / "apl-bundle/kc_globals.npy", allow_pickle=False)
|
||||||
|
require(kc_globals.dtype == np.int32 and kc_globals.shape == (4064,) and
|
||||||
|
bool(np.all(np.diff(kc_globals) > 0)) and bool(np.all((kc_globals >= 0) & (kc_globals < CFG["neurons"]))),
|
||||||
|
"Invalid frozen KC identities")
|
||||||
|
prerequisites_ok = True
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "prerequisites", "type": type(error).__name__, "message": str(error)})
|
||||||
|
if prerequisites_ok:
|
||||||
|
for row in records:
|
||||||
|
name = row["name"]
|
||||||
|
first = None
|
||||||
|
try:
|
||||||
|
case = EXP / "cases" / name
|
||||||
|
spec = read_json(case / "spec.json")
|
||||||
|
require(spec["name"] == name and spec["kind"] == "calibration" and spec["steps"] == 1000 and
|
||||||
|
spec["duration_ms"] == 100.0 and spec["dt_ms"] == .1 and spec["training"] is False and
|
||||||
|
all(spec[key] == row[key] for key in ("mode", "odor_id", "odor_index", "seed")),
|
||||||
|
"Case spec differs from fixed CAL inventory")
|
||||||
|
first = read_trial(EXP / "gpu" / (name + "-r0"), case, spec, kc_globals, CFG["neurons"], CFG["edges"])
|
||||||
|
require(first["record"]["requested"] == row["requests"], "Frozen inventory request count mismatch")
|
||||||
|
runs[(row["mode"], row["odor_id"], row["seed"])] = {key: first[key] for key in
|
||||||
|
("kc_counts", "expected_external_events", "external_events")}
|
||||||
|
run_records.append(first["record"])
|
||||||
|
provenance.append({"case": name, "repeat": 0, "state_npz_sha256": file_hash(first["output"] / "state.npz"),
|
||||||
|
"summary_sha256": file_hash(first["output"] / "summary.json")})
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "raw_trial", "case": name, "repeat": 0,
|
||||||
|
"type": type(error).__name__, "message": str(error)})
|
||||||
|
if row["seed"] == ORIGINAL_SEEDS[0]:
|
||||||
|
try:
|
||||||
|
require(first is not None, "Baseline unavailable for exact repeat")
|
||||||
|
repeat = read_trial(EXP / "gpu" / (name + "-r1"), case, spec, kc_globals, CFG["neurons"], CFG["edges"])
|
||||||
|
repeat_report = {"case": name, **exact_repeat(first, repeat)}
|
||||||
|
repeats.append(repeat_report)
|
||||||
|
provenance.append({"case": name, "repeat": 1, "state_npz_sha256": file_hash(repeat["output"] / "state.npz"),
|
||||||
|
"summary_sha256": file_hash(repeat["output"] / "summary.json")})
|
||||||
|
require(repeat_report["pass_all"], "Exact repeat differs: " + ", ".join(
|
||||||
|
key for key, value in repeat_report["checks"].items() if not value))
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "exact_repeat", "case": name, "repeat": 1,
|
||||||
|
"type": type(error).__name__, "message": str(error)})
|
||||||
|
if len(runs) == 60:
|
||||||
|
for mode in ORIGINAL_MODES:
|
||||||
|
try:
|
||||||
|
modes[mode] = summarize_mode(mode, odors, ORIGINAL_SEEDS, runs, CFG["gates"])
|
||||||
|
except Exception as error:
|
||||||
|
failures.append({"stage": "representation", "mode": mode,
|
||||||
|
"type": type(error).__name__, "message": str(error)})
|
||||||
|
integrity_pass = bool(prerequisites_ok and len(runs) == 60 and not any(row["stage"] in
|
||||||
|
("prerequisites", "raw_trial") for row in failures))
|
||||||
|
repeat_pass = bool(len(repeats) == 12 and all(row["pass_all"] for row in repeats) and
|
||||||
|
not any(row["stage"] == "exact_repeat" for row in failures))
|
||||||
|
representation_pass = bool(len(modes) == 2 and all(row["gate"] for row in modes.values()))
|
||||||
|
result = {"phase": "4AG", "scope": "Original fixed six CAL odors only; not heldout generalization or learning",
|
||||||
|
"pass_all": bool(integrity_pass and repeat_pass and representation_pass),
|
||||||
|
"numerical_integrity_pass": integrity_pass, "exact_repeat_pass": repeat_pass,
|
||||||
|
"original_representation_gate_pass": representation_pass,
|
||||||
|
"expected_base_trials": 60, "valid_base_trials": len(runs), "expected_repeats": 12,
|
||||||
|
"checked_repeats": len(repeats), "seeds": list(ORIGINAL_SEEDS), "duration_ms": 100.0,
|
||||||
|
"odor_ids": odors, "modes": modes, "runs": run_records, "repeats": repeats,
|
||||||
|
"failures": failures, "input_output_provenance": provenance, "encoder_audit": encoder,
|
||||||
|
"metric_source": "phase4l.representation (full original gate), phase4i.pair_metrics",
|
||||||
|
"finite_gate_note": "Added integrity prerequisite; original 4L recorded finite but omitted it from its gate",
|
||||||
|
"repeat_gate_note": "Additional exact repeat requirement; original metrics and numerical thresholds unchanged",
|
||||||
|
"shared_apl_component_oracle_limit": True, "independent_oracle_equivalence_claim": False,
|
||||||
|
"candidate_generated": False, "training": False, "heldout_dynamic_access": False}
|
||||||
|
if target is not None:
|
||||||
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with target.open("x", encoding="utf-8") as output:
|
||||||
|
json.dump(result, output, ensure_ascii=False, indent=2, allow_nan=False)
|
||||||
|
output.write("\n")
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(json.dumps({key: value for key, value in summarize().items() if key in
|
||||||
|
("pass_all", "numerical_integrity_pass", "exact_repeat_pass", "original_representation_gate_pass")}), flush=True)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
49f53924f758317bfcbd2b53cab9b8b785121eb99f3234a8343c9b483c5701d8 PROTOCOL.md
|
||||||
|
edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c calibration.py
|
||||||
|
6e1616b086f667fa4e4b5087f500f8080281977ca9922e7b055acfddd2003bd5 compare.py
|
||||||
|
a8bafb9deec49d918976f2836d977ef9f13c26a6fb7f70e015879e29cf986c9a config.json
|
||||||
|
274eb13ccf38dbbc5c7f14d9d642130eb0f69072d91a090f208c30c27f87dd2b context.py
|
||||||
|
b6e3c67e668a971b544df32d76435ab5e537061b9fc2e8d9dedb5d2a726f5782 finalize.py
|
||||||
|
69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a gpu_apl.py
|
||||||
|
21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291 legacy_apl_worker.py
|
||||||
|
357a7d3debb5abc34a8714c0233b456547a154d9d5855d28661b4f01019a80ea oracle_apl.py
|
||||||
|
e9328567753e144fc315491970f7e02af13725b93f35e4d4b97f7c4c48ce3338 prepare.py
|
||||||
|
afbe6d5a37c29bda66d38c470093584130d1852e67881c681662aec3c76b33c7 run_case.py
|
||||||
|
84c681030b0032119b5392d0c3f3c136a9c6b0d133eb548c40791a10bbbb8b63 run_suite.py
|
||||||
|
bab3136eecbc5bb09a985d715844ee845cb72b07930ce376bfb39be33bd1845a test_calibration.py
|
||||||
|
1a233f47943e01bbd845ac1dacdb1eec3f88c270c65a5f75bce1cf679b5de097 test_protocol.py
|
||||||
|
0ed665f686e3499f8543e48f1712ccb4523946971cb7a0e096cf4f6d10d3bcba test_python_entry.py
|
||||||
|
5cfc9a4505da6b8fb4e7d2617cdaedaa8475ed46a11ec9bdf0d4d25b1d22c2d3 validate_components.py
|
||||||
|
0d0e72b2f1348f6648124c8c34f75094f76fc5e1a281fbcca130a5fad2f35293 verify_frozen.py
|
||||||
|
208c00961b9d895d14ac050bc23fbc18db49d0df1fcf5c20d4c3eaa8e15ff7ff manifest.json
|
||||||
@@ -0,0 +1,508 @@
|
|||||||
|
"""Fail-closed byte-exact audit of the shared-APL closed-loop fixtures.
|
||||||
|
|
||||||
|
Comparison is independent of either backend's stored PASS. No tolerance is
|
||||||
|
used, timing fields are never compared, and reports contain no wall timestamp.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import struct
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
N_GLOBAL = 166700
|
||||||
|
STATE_KEYS = ('step', 'neuron_idx', 'counts', 'v', 'g', 'ref')
|
||||||
|
REQUEST_FIELDS = ('tick', 'neuron_idx', 'attempted', 'accepted', 'rejected')
|
||||||
|
HASH_FIELDS = {'tick', 'v_sha256', 'g_sha256', 'ref_sha256'}
|
||||||
|
QUEUE_FIELDS = {'tick', 'count', 'accepted_count', 'ordered_edge_sha256',
|
||||||
|
'accepted_mask_sha256', 'joint_sha256'}
|
||||||
|
BUNDLE_FILES = ('input_matrix.npy', 'output_matrix.npy', 'kc_globals.npy', 'apl_globals.npy')
|
||||||
|
COEFFICIENTS = ('gd', 'c0', 'cg', 'cv', 'threshold', 'reset', 'seed_volt')
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def file_hash(path):
|
||||||
|
h = hashlib.sha256()
|
||||||
|
with Path(path).open('rb') as source:
|
||||||
|
for block in iter(lambda: source.read(8 << 20), b''):
|
||||||
|
h.update(block)
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def raw_hash(array, dtype=None):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(array, dtype=dtype).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def save(path, report):
|
||||||
|
if path is None:
|
||||||
|
return
|
||||||
|
path = Path(path)
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with path.open('x', encoding='utf-8') as target:
|
||||||
|
json.dump(report, target, indent=2, sort_keys=True, allow_nan=False)
|
||||||
|
target.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def _read_json(path, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
return json.loads(Path(path).read_text(encoding='utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
def _read_jsonl(path, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
with Path(path).open(encoding='utf-8') as source:
|
||||||
|
return [json.loads(line) for line in source if line.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
def _read_array(path, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
return np.load(path, mmap_mode='r', allow_pickle=False)
|
||||||
|
|
||||||
|
|
||||||
|
def _check(checks, name, condition):
|
||||||
|
checks[name] = bool(condition)
|
||||||
|
|
||||||
|
|
||||||
|
def _bit_mask(a, b):
|
||||||
|
if a.dtype.kind == 'f':
|
||||||
|
unsigned = np.dtype('uint'+str(a.dtype.itemsize*8))
|
||||||
|
return np.ascontiguousarray(a).view(unsigned) != np.ascontiguousarray(b).view(unsigned)
|
||||||
|
return a != b
|
||||||
|
|
||||||
|
|
||||||
|
def _compare_array(name, a, b, checks, differences, dtype=None, shape=None):
|
||||||
|
a, b = np.asarray(a), np.asarray(b)
|
||||||
|
schema = a.shape == b.shape and a.dtype == b.dtype and \
|
||||||
|
(dtype is None or a.dtype == np.dtype(dtype)) and (shape is None or a.shape == shape)
|
||||||
|
_check(checks, name+'.schema', schema)
|
||||||
|
if not schema:
|
||||||
|
differences[name] = {'left_shape': list(a.shape), 'right_shape': list(b.shape),
|
||||||
|
'left_dtype': str(a.dtype), 'right_dtype': str(b.dtype), 'expected_shape': None if shape is None else list(shape),
|
||||||
|
'expected_dtype': None if dtype is None else str(np.dtype(dtype))}
|
||||||
|
_check(checks, name+'.bitwise_exact', False)
|
||||||
|
return False
|
||||||
|
finite = bool(np.isfinite(a).all() and np.isfinite(b).all())
|
||||||
|
_check(checks, name+'.finite', finite)
|
||||||
|
mask = _bit_mask(a, b)
|
||||||
|
exact = not bool(np.any(mask))
|
||||||
|
_check(checks, name+'.bitwise_exact', exact)
|
||||||
|
if not exact or not finite:
|
||||||
|
flat = np.flatnonzero(mask.ravel())
|
||||||
|
detail = {'mismatching_elements': int(len(flat)),
|
||||||
|
'first_positions': [list(map(int, np.unravel_index(int(index), a.shape))) for index in flat[:5]],
|
||||||
|
'left_nonfinite': int(np.count_nonzero(~np.isfinite(a))),
|
||||||
|
'right_nonfinite': int(np.count_nonzero(~np.isfinite(b)))}
|
||||||
|
if finite and a.size:
|
||||||
|
error = np.abs(a.astype(np.float64)-b.astype(np.float64))
|
||||||
|
detail.update(max_abs_error=float(error.max()), mean_abs_error=float(error.mean()))
|
||||||
|
if a.dtype.kind == 'f' and len(flat):
|
||||||
|
unsigned = np.dtype('uint'+str(a.dtype.itemsize*8))
|
||||||
|
av = np.ascontiguousarray(a).view(unsigned).ravel()
|
||||||
|
bv = np.ascontiguousarray(b).view(unsigned).ravel()
|
||||||
|
detail['first_bit_patterns'] = [{'left': hex(int(av[index])), 'right': hex(int(bv[index]))} for index in flat[:5]]
|
||||||
|
differences[name] = detail
|
||||||
|
return exact and finite
|
||||||
|
|
||||||
|
|
||||||
|
def _sha(value):
|
||||||
|
return isinstance(value, str) and re.fullmatch('[0-9a-f]{64}', value) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _read_requests(path, steps, used):
|
||||||
|
used.add(Path(path))
|
||||||
|
with Path(path).open(encoding='utf-8', newline='') as source:
|
||||||
|
reader = csv.DictReader(source)
|
||||||
|
require(tuple(reader.fieldnames or ()) == REQUEST_FIELDS, 'Request CSV schema mismatch: '+str(path))
|
||||||
|
rows = [{key: int(row[key]) for key in REQUEST_FIELDS} for row in reader]
|
||||||
|
previous = (-1, -1)
|
||||||
|
for row in rows:
|
||||||
|
key = row['tick'], row['neuron_idx']
|
||||||
|
require(previous < key and 0 <= key[0] < steps and 0 <= key[1] < N_GLOBAL,
|
||||||
|
'Request rows must be sorted, unique, and in range: '+str(path))
|
||||||
|
require(row['attempted'] == 1 and row['accepted'] in (0, 1) and row['rejected'] == 1-row['accepted'],
|
||||||
|
'Request accounting is incomplete: '+str(path))
|
||||||
|
previous = key
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def _load_run(directory, role, n, edges, steps, record_history, name, used, checks):
|
||||||
|
directory = Path(directory)
|
||||||
|
summary = _read_json(directory/'summary.json', used)
|
||||||
|
_check(checks, role+'.summary_complete', summary.get('complete') is True and summary.get('pass_all') is True and
|
||||||
|
summary.get('steps') == steps and summary.get('completed_ticks') == steps and
|
||||||
|
summary.get('nodes') == n and summary.get('edges') == edges and summary.get('precision') == 'float64')
|
||||||
|
is_cpu = role == 'cpu'
|
||||||
|
_check(checks, role+'.case_name', summary.get('name' if is_cpu else 'case') == name)
|
||||||
|
_check(checks, role+'.history_mode', summary.get('history_recorded' if is_cpu else 'record_history') is record_history)
|
||||||
|
_check(checks, role+'.apl_precision', summary.get('APL_precision' if is_cpu else 'apl_precision') == 'float32')
|
||||||
|
_check(checks, role+'.no_error_marker', not (directory/'error.json').exists())
|
||||||
|
used.add(directory/'state.npz')
|
||||||
|
with np.load(directory/'state.npz', allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == set(STATE_KEYS), 'State NPZ keys changed: '+str(directory))
|
||||||
|
state = {key: source[key].copy() for key in STATE_KEYS}
|
||||||
|
for key, dtype in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32'), ('counts', 'int32')):
|
||||||
|
require(state[key].shape == (n,) and state[key].dtype == np.dtype(dtype), 'Invalid final '+key+': '+str(directory))
|
||||||
|
require(state['step'].dtype == state['neuron_idx'].dtype == np.int32 and state['step'].ndim == 1 and
|
||||||
|
state['step'].shape == state['neuron_idx'].shape, 'Invalid sparse event schema: '+str(directory))
|
||||||
|
require(bool(np.all((state['step'] >= 0) & (state['step'] < steps))) and
|
||||||
|
bool(np.all((state['neuron_idx'] >= 0) & (state['neuron_idx'] < N_GLOBAL))), 'Sparse event range error')
|
||||||
|
event_keys = state['step'].astype(np.int64)*N_GLOBAL+state['neuron_idx']
|
||||||
|
_check(checks, role+'.events_sorted_unique', len(event_keys) < 2 or np.all(np.diff(event_keys) > 0))
|
||||||
|
_check(checks, role+'.count_nonnegative_total', np.all(state['counts'] >= 0) and int(state['counts'].sum()) == len(event_keys))
|
||||||
|
_check(checks, role+'.ref_range', np.all((state['ref'] >= 0) & (state['ref'] <= 22)))
|
||||||
|
_check(checks, role+'.reported_events', summary.get('spikes' if is_cpu else 'total_spikes') == len(event_keys))
|
||||||
|
hashes = _read_jsonl(directory/'tick-state-hashes.jsonl', used)
|
||||||
|
require(len(hashes) == steps and [row.get('tick') for row in hashes] == list(range(steps)), 'Incomplete tick hash coverage')
|
||||||
|
require(all(set(row) == HASH_FIELDS and all(_sha(row[key]) for key in HASH_FIELDS-{'tick'}) for row in hashes),
|
||||||
|
'Invalid tick state hash schema')
|
||||||
|
queues = _read_jsonl(directory/'queue.jsonl', used)
|
||||||
|
require(len(queues) == steps and [row.get('tick') for row in queues] == list(range(steps)), 'Incomplete queue coverage')
|
||||||
|
require(all(set(row) == QUEUE_FIELDS and type(row['count']) is int and type(row['accepted_count']) is int and
|
||||||
|
0 <= row['accepted_count'] <= row['count'] <= edges and
|
||||||
|
all(_sha(row[key]) for key in QUEUE_FIELDS-{'tick', 'count', 'accepted_count'}) for row in queues),
|
||||||
|
'Invalid queue row schema/count/hash')
|
||||||
|
for key in ('v', 'g', 'ref'):
|
||||||
|
_check(checks, role+'.last_hash_'+key, hashes[-1][key+'_sha256'] == raw_hash(state[key], '<i4' if key == 'ref' else '<f8'))
|
||||||
|
requests = _read_requests(directory/'requests.csv', steps, used)
|
||||||
|
requested, accepted = len(requests), sum(row['accepted'] for row in requests)
|
||||||
|
_check(checks, role+'.request_summary', summary.get('requests' if is_cpu else 'requested') == requested and
|
||||||
|
summary.get('applicable_requests' if is_cpu else 'accepted_requests') == accepted and
|
||||||
|
summary.get('ref_rejected_requests' if is_cpu else 'rejected_requests') == requested-accepted)
|
||||||
|
apl = {field: _read_array(directory/('apl-'+field+'.float32.npy'), used) for field in ('drive', 'state', 'inhibition')}
|
||||||
|
for field, width in (('drive', 2), ('state', 2), ('inhibition', 4064)):
|
||||||
|
require(apl[field].dtype == np.float32 and apl[field].shape == (steps, width), 'Invalid APL '+field+' history schema')
|
||||||
|
_check(checks, role+'.apl_positive_'+field, np.all(apl[field] >= 0))
|
||||||
|
histories, pre = {}, {}
|
||||||
|
for field, dtype in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32')):
|
||||||
|
files = (directory/(field+'-history.'+dtype+'.npy'), directory/('preAPL-'+field+'.'+dtype+'.npy'))
|
||||||
|
if record_history:
|
||||||
|
histories[field], pre[field] = (_read_array(path, used) for path in files)
|
||||||
|
require(all(array.dtype == np.dtype(dtype) and array.shape == (steps, n) for array in (histories[field], pre[field])),
|
||||||
|
'Small pre/post history schema mismatch')
|
||||||
|
_check(checks, role+'.history_hashes_'+field, all(row[field+'_sha256'] == raw_hash(histories[field][tick])
|
||||||
|
for tick, row in enumerate(hashes)))
|
||||||
|
_check(checks, role+'.history_final_'+field, not np.any(_bit_mask(histories[field][-1], state[field])))
|
||||||
|
else:
|
||||||
|
_check(checks, role+'.no_dense_'+field, not any(path.exists() for path in files))
|
||||||
|
if is_cpu:
|
||||||
|
component = _read_json(directory/'apl-worker-handshake.json', used)['handshake']
|
||||||
|
else:
|
||||||
|
component = _read_json(directory/'apl-component.json', used)
|
||||||
|
_check(checks, role+'.component_summary_consistent', summary.get('apl_component') == component)
|
||||||
|
return dict(directory=directory, summary=summary, state=state, hashes=hashes, queues=queues,
|
||||||
|
requests=requests, apl=apl, histories=histories, pre=pre, component=component)
|
||||||
|
|
||||||
|
|
||||||
|
def _pair_outputs(left, right, checks, differences, n, steps, record_history):
|
||||||
|
for field in STATE_KEYS:
|
||||||
|
shape = None if field in ('step', 'neuron_idx') else (n,)
|
||||||
|
dtype = 'float64' if field in ('v', 'g') else 'int32'
|
||||||
|
_compare_array('state.'+field, left['state'][field], right['state'][field], checks, differences, dtype, shape)
|
||||||
|
for field, width in (('drive', 2), ('state', 2), ('inhibition', 4064)):
|
||||||
|
_compare_array('apl.'+field, left['apl'][field], right['apl'][field], checks, differences, 'float32', (steps, width))
|
||||||
|
for field in ('hashes', 'queues', 'requests', 'component'):
|
||||||
|
same = left[field] == right[field]
|
||||||
|
_check(checks, field+'.parsed_exact', same)
|
||||||
|
if not same:
|
||||||
|
if isinstance(left[field], list):
|
||||||
|
first = next((i for i, (a, b) in enumerate(zip(left[field], right[field])) if a != b), None)
|
||||||
|
differences[field] = {'left_count': len(left[field]), 'right_count': len(right[field]),
|
||||||
|
'first_differing_row': first,
|
||||||
|
'left_row': None if first is None else left[field][first],
|
||||||
|
'right_row': None if first is None else right[field][first]}
|
||||||
|
else:
|
||||||
|
differences[field] = {'left': left[field], 'right': right[field]}
|
||||||
|
if record_history:
|
||||||
|
for stage in ('histories', 'pre'):
|
||||||
|
for field, dtype in (('v', 'float64'), ('g', 'float64'), ('ref', 'int32')):
|
||||||
|
_compare_array(stage+'.'+field, left[stage][field], right[stage][field], checks, differences, dtype, (steps, n))
|
||||||
|
|
||||||
|
|
||||||
|
def _queue_digest(tick, ids, accepted):
|
||||||
|
ids = np.ascontiguousarray(ids, dtype='<i8').tobytes()
|
||||||
|
mask = np.ascontiguousarray(accepted, dtype=np.uint8).tobytes()
|
||||||
|
return {'tick': tick, 'count': len(mask), 'accepted_count': int(np.count_nonzero(accepted)),
|
||||||
|
'ordered_edge_sha256': hashlib.sha256(ids).hexdigest(),
|
||||||
|
'accepted_mask_sha256': hashlib.sha256(mask).hexdigest(),
|
||||||
|
'joint_sha256': hashlib.sha256(b'phase4af-queue-v1\0'+struct.pack('<qq', tick, len(mask))+ids+mask).hexdigest()}
|
||||||
|
|
||||||
|
|
||||||
|
def _independent_event_accounting(run, role, graph, requested, steps, checks, differences):
|
||||||
|
nodes, ptr = graph['nodes'], graph['ptr']
|
||||||
|
n = len(nodes)
|
||||||
|
state = run['state']
|
||||||
|
local = np.searchsorted(nodes, state['neuron_idx'])
|
||||||
|
require(np.all(local < n) and np.array_equal(nodes[local], state['neuron_idx']), 'Actual spike outside graph identity')
|
||||||
|
_check(checks, role+'.events_per_neuron_counts', np.array_equal(np.bincount(local, minlength=n), state['counts']))
|
||||||
|
actual_request_pairs = [(row['tick'], row['neuron_idx']) for row in run['requests']]
|
||||||
|
_check(checks, role+'.requests_match_frozen_input', actual_request_pairs == requested)
|
||||||
|
require(actual_request_pairs == requested, 'Actual request population/time differs from frozen input')
|
||||||
|
bounds = np.searchsorted(state['step'], np.arange(steps+1))
|
||||||
|
request_ticks = np.asarray([row['tick'] for row in run['requests']], np.int32)
|
||||||
|
rbounds = np.searchsorted(request_ticks, np.arange(steps+1))
|
||||||
|
request_nodes = np.asarray([row['neuron_idx'] for row in run['requests']], np.int32)
|
||||||
|
request_local = np.searchsorted(nodes, request_nodes)
|
||||||
|
require(np.all(request_local < n) and np.array_equal(nodes[request_local], request_nodes), 'Request outside graph')
|
||||||
|
last = np.full(n, -1_000_000_000, np.int64)
|
||||||
|
degrees = np.diff(ptr)
|
||||||
|
expected_counts = np.zeros(steps, np.int64)
|
||||||
|
arrival_tick = state['step'].astype(np.int64)+18
|
||||||
|
valid = arrival_tick < steps
|
||||||
|
np.add.at(expected_counts, arrival_tick[valid], degrees[local[valid]])
|
||||||
|
_check(checks, role+'.delayed_all_edges_count', np.array_equal(expected_counts, [row['count'] for row in run['queues']]))
|
||||||
|
request_ok, delivered_ok, ref_ok, queue_ok, reset_ok = True, True, True, True, True
|
||||||
|
first = {}
|
||||||
|
for tick in range(steps):
|
||||||
|
fired = local[bounds[tick]:bounds[tick+1]]
|
||||||
|
lo, hi = rbounds[tick:tick+2]
|
||||||
|
targets = request_local[lo:hi]
|
||||||
|
accepted = (tick-last[targets]) >= 22
|
||||||
|
for index, ok in zip(range(lo, hi), accepted):
|
||||||
|
row = run['requests'][index]
|
||||||
|
if row['accepted'] != int(ok) or row['rejected'] != int(not ok):
|
||||||
|
request_ok = False
|
||||||
|
first.setdefault('request_ref_mismatch', {'tick': tick, 'neuron_idx': row['neuron_idx']})
|
||||||
|
if not np.isin(targets[accepted], fired).all() or np.isin(targets[~accepted], fired).any():
|
||||||
|
delivered_ok = False
|
||||||
|
first.setdefault('request_delivery_mismatch', tick)
|
||||||
|
last[fired] = tick
|
||||||
|
ref = np.maximum(22-(tick-last), 0).astype(np.int32)
|
||||||
|
if raw_hash(ref, '<i4') != run['hashes'][tick]['ref_sha256']:
|
||||||
|
ref_ok = False
|
||||||
|
first.setdefault('ref_hash_mismatch', tick)
|
||||||
|
if run['pre']:
|
||||||
|
if len(fired) and not np.array_equal(np.ascontiguousarray(run['pre']['g'][tick, fired]).view(np.uint64), np.zeros(len(fired), np.uint64)):
|
||||||
|
reset_ok = False
|
||||||
|
first.setdefault('pre_apl_spike_reset_mismatch', tick)
|
||||||
|
due = local[bounds[tick-18]:bounds[tick-17]] if tick >= 18 else np.empty(0, np.int64)
|
||||||
|
chunks = [np.arange(ptr[source], ptr[source+1], dtype=np.int64) for source in due]
|
||||||
|
indices = np.concatenate(chunks) if chunks else np.empty(0, np.int64)
|
||||||
|
expected_queue = _queue_digest(tick, graph['edge_id'][indices], (ref[graph['dst'][indices]] == 0).astype(np.uint8))
|
||||||
|
if expected_queue != run['queues'][tick]:
|
||||||
|
queue_ok = False
|
||||||
|
first.setdefault('queue_reconstruction_mismatch', tick)
|
||||||
|
_check(checks, role+'.request_refractory_gate', request_ok)
|
||||||
|
_check(checks, role+'.accepted_spikes_rejected_absent', delivered_ok)
|
||||||
|
_check(checks, role+'.all_ref_hashes_from_actual_events', ref_ok)
|
||||||
|
if run['pre']:
|
||||||
|
_check(checks, role+'.small_queue_independent_reconstruction', queue_ok)
|
||||||
|
_check(checks, role+'.spike_g_reset_before_apl', reset_ok)
|
||||||
|
if first:
|
||||||
|
differences[role+'.independent_accounting'] = first
|
||||||
|
|
||||||
|
|
||||||
|
def _check_apl_application(run, role, nodes, kc, checks, differences):
|
||||||
|
if not run['pre']:
|
||||||
|
return
|
||||||
|
common, local_kc, bundle_kc = np.intersect1d(nodes, kc, assume_unique=True, return_indices=True)
|
||||||
|
_compare_array(role+'.apl_keeps_voltage', run['pre']['v'], run['histories']['v'], checks, differences, 'float64')
|
||||||
|
_compare_array(role+'.apl_keeps_ref', run['pre']['ref'], run['histories']['ref'], checks, differences, 'int32')
|
||||||
|
expected = np.array(run['pre']['g'], copy=True)
|
||||||
|
delta = run['apl']['inhibition'][:, bundle_kc].astype(np.float64)*np.float64(.001)
|
||||||
|
expected[:, local_kc] = expected[:, local_kc]-delta
|
||||||
|
_compare_array(role+'.apl_unconditional_g_write', expected, run['histories']['g'], checks, differences, 'float64')
|
||||||
|
|
||||||
|
|
||||||
|
def _finish(report, checks, differences, used, out_json):
|
||||||
|
report['checks'] = {name: bool(value) for name, value in checks.items()}
|
||||||
|
report['differences'] = differences
|
||||||
|
report['pass_all'] = bool(checks) and all(checks.values()) and 'error' not in report
|
||||||
|
report['failed_checks'] = sorted(name for name, value in checks.items() if not value)
|
||||||
|
report['evidence_sha256'] = {str(path): file_hash(path) for path in sorted(used) if path.is_file()}
|
||||||
|
save(out_json, report)
|
||||||
|
return report
|
||||||
|
|
||||||
|
|
||||||
|
def compare(case_dir, gpu_dir, cpu_dir, out_json=None):
|
||||||
|
"""Strict independent closed-loop comparison; out_json=None is read-only."""
|
||||||
|
case_dir, gpu_dir, cpu_dir = Path(case_dir), Path(gpu_dir), Path(cpu_dir)
|
||||||
|
if out_json is not None:
|
||||||
|
require(not Path(out_json).exists(), 'Refusing existing comparison report')
|
||||||
|
checks, differences, used = {}, {}, set()
|
||||||
|
report = {'kind': 'shared-APL-component closed-loop byte-exact comparison', 'pass_all': False,
|
||||||
|
'case_dir': str(case_dir), 'gpu_dir': str(gpu_dir), 'cpu_dir': str(cpu_dir),
|
||||||
|
'tolerance': None, 'signed_zero_included': True, 'timing_fields_compared': False,
|
||||||
|
'independent_CPU_all_components_claim': False}
|
||||||
|
try:
|
||||||
|
spec = _read_json(case_dir/'spec.json', used)
|
||||||
|
steps, history = spec['steps'], spec['record_history']
|
||||||
|
require(type(steps) is int and steps > 0 and type(history) is bool and spec['dt_ms'] == .1,
|
||||||
|
'Invalid fixed case clock/history schema')
|
||||||
|
graph_dir, bundle_dir = Path(spec['graph_dir']), Path(spec['apl_bundle_dir'])
|
||||||
|
graph = {field: _read_array(graph_dir/(field+'.npy'), used) for field in
|
||||||
|
('nodes', 'edge_id', 'src', 'dst', 'ptr', 'signed_raw', 'weights')}
|
||||||
|
nodes = graph['nodes']
|
||||||
|
n, edges = len(nodes), len(graph['edge_id'])
|
||||||
|
require(n > 0 and edges > 0 and nodes.dtype == np.int32 and nodes.ndim == 1 and np.all((nodes >= 0) & (nodes < N_GLOBAL)) and
|
||||||
|
np.all(np.diff(nodes) > 0), 'Invalid canonical node identities')
|
||||||
|
require(graph['ptr'].dtype == np.int64 and graph['ptr'].shape == (n+1,) and graph['ptr'][0] == 0 and
|
||||||
|
graph['ptr'][-1] == edges and np.all(np.diff(graph['ptr']) >= 0), 'Invalid CSR')
|
||||||
|
for key, dtype in (('edge_id', 'int64'), ('src', 'int32'), ('dst', 'int32'), ('signed_raw', 'int64'), ('weights', 'float64')):
|
||||||
|
require(graph[key].dtype == np.dtype(dtype) and graph[key].shape == (edges,), 'Invalid graph '+key)
|
||||||
|
require(np.array_equal(graph['src'], np.repeat(np.arange(n, dtype=np.int32), np.diff(graph['ptr']))) and
|
||||||
|
np.all((graph['dst'] >= 0) & (graph['dst'] < n)), 'Invalid source/destination row mapping')
|
||||||
|
require(history == (n < 512) and (n < 512 or n == N_GLOBAL), 'Invalid small/full history declaration')
|
||||||
|
require(np.all(graph['edge_id'] >= 0) and np.all(np.diff(graph['edge_id']) > 0),
|
||||||
|
'Original canonical edge IDs must be unique and increasing')
|
||||||
|
if n == N_GLOBAL:
|
||||||
|
require(edges == 25582938 and np.array_equal(nodes, np.arange(n, dtype=np.int32)) and
|
||||||
|
np.array_equal(graph['edge_id'], np.arange(edges, dtype=np.int64)), 'Full canonical graph identity changed')
|
||||||
|
bundle = {name: _read_array(bundle_dir/name, used) for name in BUNDLE_FILES}
|
||||||
|
kc, apl_ids = bundle['kc_globals.npy'], bundle['apl_globals.npy']
|
||||||
|
require(kc.dtype == apl_ids.dtype == np.int32 and kc.shape == (4064,) and apl_ids.shape == (2,), 'Invalid APL/KC identities')
|
||||||
|
require(np.all((kc >= 0) & (kc < N_GLOBAL)) and np.all(np.diff(kc) > 0) and
|
||||||
|
np.all((apl_ids >= 0) & (apl_ids < N_GLOBAL)) and np.all(np.diff(apl_ids) > 0) and
|
||||||
|
not np.intersect1d(kc, apl_ids).size, 'APL/KC identities overlap or are invalid')
|
||||||
|
for key, shape in (('input_matrix.npy', (2, N_GLOBAL)), ('output_matrix.npy', (2, 4064))):
|
||||||
|
require(bundle[key].dtype == np.float32 and bundle[key].shape == shape and
|
||||||
|
np.isfinite(bundle[key]).all() and np.all(bundle[key] >= 0), 'Invalid normalized APL matrix')
|
||||||
|
gpu = _load_run(gpu_dir, 'gpu', n, edges, steps, history, spec['name'], used, checks)
|
||||||
|
cpu = _load_run(cpu_dir, 'cpu', n, edges, steps, history, spec['name'], used, checks)
|
||||||
|
_pair_outputs(gpu, cpu, checks, differences, n, steps, history)
|
||||||
|
used.add(case_dir/'requests.npz')
|
||||||
|
with np.load(case_dir/'requests.npz', allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == {'tick', 'neuron_idx'} and source['tick'].dtype == source['neuron_idx'].dtype == np.int32,
|
||||||
|
'Fixed request NPZ schema changed')
|
||||||
|
require(source['tick'].shape == source['neuron_idx'].shape and source['tick'].ndim == 1, 'Invalid sparse request shape')
|
||||||
|
requested = list(zip(map(int, source['tick']), map(int, source['neuron_idx'])))
|
||||||
|
for role, run in (('gpu', gpu), ('cpu', cpu)):
|
||||||
|
_independent_event_accounting(run, role, graph, requested, steps, checks, differences)
|
||||||
|
_check_apl_application(run, role, nodes, kc, checks, differences)
|
||||||
|
|
||||||
|
# Independently derive the effective clone. Original graph weights stay read-only.
|
||||||
|
cpu_weights = _read_array(cpu_dir/'weights.npy', used)
|
||||||
|
require(cpu_weights.dtype == np.float64 and cpu_weights.shape == (edges,), 'CPU effective weight schema mismatch')
|
||||||
|
expected_hash, base_hash, mask_hash = hashlib.sha256(), hashlib.sha256(), hashlib.sha256()
|
||||||
|
weight_ok, mask_count = True, 0
|
||||||
|
for start in range(0, edges, 1 << 20):
|
||||||
|
stop = min(edges, start+(1 << 20))
|
||||||
|
original = np.asarray(graph['weights'][start:stop])
|
||||||
|
require(np.isfinite(original).all(), 'Nonfinite original weights')
|
||||||
|
raw_expected = graph['signed_raw'][start:stop]*(.275*.001)
|
||||||
|
require(not np.any(_bit_mask(original, raw_expected)), 'Original SI weights differ from unaltered signed contacts')
|
||||||
|
mask = np.isin(nodes[graph['src'][start:stop]], apl_ids)
|
||||||
|
expected = original.copy()
|
||||||
|
expected[mask] = np.float64(0)
|
||||||
|
mask_count += int(mask.sum())
|
||||||
|
expected_hash.update(np.ascontiguousarray(expected, dtype='<f8').tobytes())
|
||||||
|
base_hash.update(np.ascontiguousarray(original, dtype='<f8').tobytes())
|
||||||
|
mask_hash.update(np.ascontiguousarray(graph['edge_id'][start:stop][mask], dtype='<i8').tobytes())
|
||||||
|
weight_ok &= not np.any(_bit_mask(expected, cpu_weights[start:stop]))
|
||||||
|
expected_sha = expected_hash.hexdigest()
|
||||||
|
_check(checks, 'cpu.effective_weights_independent_bytes', weight_ok)
|
||||||
|
for role, run in (('gpu', gpu), ('cpu', cpu)):
|
||||||
|
_check(checks, role+'.effective_weights_raw_sha', run['summary'].get('effective_weights_raw_sha256') == expected_sha)
|
||||||
|
_check(checks, role+'.apl_fast_edge_count', run['summary'].get('apl_fast_edges_zeroed') == mask_count)
|
||||||
|
_check(checks, role+'.kc_target_count', run['summary'].get('kc_targets_present') == len(np.intersect1d(nodes, kc)))
|
||||||
|
mask_audit = _read_json(cpu_dir/'apl-mask-audit.json', used)
|
||||||
|
_check(checks, 'cpu.mask_provenance', mask_audit['count'] == mask_count and
|
||||||
|
mask_audit['ordered_original_edge_id_sha256'] == mask_hash.hexdigest() and
|
||||||
|
mask_audit['base_weight_raw_bytes_sha256'] == base_hash.hexdigest() and
|
||||||
|
mask_audit['effective_weights_raw_sha256'] == expected_sha and mask_audit['base_graph_files_modified'] is False)
|
||||||
|
|
||||||
|
case_hashes = {name: file_hash(case_dir/name) for name in ('spec.json', 'requests.npz')}
|
||||||
|
if (case_dir/'arrays.npz').exists():
|
||||||
|
case_hashes['arrays.npz'] = file_hash(case_dir/'arrays.npz')
|
||||||
|
used.add(case_dir/'arrays.npz')
|
||||||
|
baseline_coeff = _read_json(Path(spec['coefficients_path']), used)
|
||||||
|
actual_coeff = _read_json(cpu_dir/'coefficients.json', used)
|
||||||
|
_check(checks, 'cpu.actual_author_coefficients_exact', all(float(actual_coeff[key]).hex() == float(baseline_coeff[key]).hex()
|
||||||
|
for key in COEFFICIENTS))
|
||||||
|
audit = _read_json(cpu_dir/'input-audit.json', used)
|
||||||
|
expected_graph_hashes = {name: file_hash(graph_dir/name) for name in
|
||||||
|
tuple(field+'.npy' for field in graph)+('completeness.csv', 'connectivity.parquet')}
|
||||||
|
bundle_hashes = {name: file_hash(bundle_dir/name) for name in BUNDLE_FILES}
|
||||||
|
_check(checks, 'cpu.read_actual_case', audit['spec'] == spec and audit['case_hashes'] == case_hashes)
|
||||||
|
_check(checks, 'cpu.graph_hashes', audit['graph_hashes'] == expected_graph_hashes)
|
||||||
|
_check(checks, 'cpu.bundle_hashes', audit['bundle_hashes'] == bundle_hashes)
|
||||||
|
_check(checks, 'cpu.no_candidate_trace_input', audit.get('candidate_trace_used_as_input') is False and
|
||||||
|
cpu['summary'].get('candidate_trace_used_as_input') is False)
|
||||||
|
_check(checks, 'cpu.worker_source_hash', audit['legacy_apl_worker_sha256'] == file_hash(spec['legacy_apl_worker']))
|
||||||
|
_check(checks, 'cpu.coefficient_input_hash', audit['coefficients_sha256'] == file_hash(spec['coefficients_path']))
|
||||||
|
gpu_hashes = dict(case_hashes, **{'base_weights.npy': file_hash(graph_dir/'weights.npy'),
|
||||||
|
'coefficients.json': file_hash(spec['coefficients_path'])})
|
||||||
|
_check(checks, 'gpu.input_hashes', gpu['summary']['input_sha256'] == gpu_hashes)
|
||||||
|
for role, run in (('gpu', gpu), ('cpu', cpu)):
|
||||||
|
component = run['component']
|
||||||
|
_check(checks, role+'.actual_component_bundle_bytes', component['files_sha256'] == bundle_hashes and
|
||||||
|
component['array_sha256'] == {name: raw_hash(value) for name, value in bundle.items()})
|
||||||
|
_check(checks, role+'.component_dimensions_clock', component.get('ok') is True and
|
||||||
|
component['protocol'] == 'phase4ag-apl-v1' and component['n_neurons'] == N_GLOBAL and
|
||||||
|
component['n_apl'] == 2 and component['n_kc'] == 4064 and component['dt_ms'] == .1)
|
||||||
|
decay = np.float32(math.exp(-.1/20.0))
|
||||||
|
gain = np.float32(.01)
|
||||||
|
_check(checks, role+'.frozen_apl_constants', component['decay_f32_bits'] == f'{int(decay.view(np.uint32)):08x}' and
|
||||||
|
component['gain_f32_bits'] == f'{int(gain.view(np.uint32)):08x}')
|
||||||
|
env = component['environment']
|
||||||
|
_check(checks, role+'.component_precision_environment', env['cuda_matmul_allow_tf32'] is False and
|
||||||
|
env['float32_matmul_precision'] == 'highest' and env['precision_configuration_changed_by_component'] is False and
|
||||||
|
'4090' in env['device_name'])
|
||||||
|
environment = _read_json(cpu_dir/'environment.json', used)
|
||||||
|
_check(checks, 'cpu.pinned_environment', environment['packages']['brian2'] == '2.5.1' and
|
||||||
|
environment['packages']['numpy'] == '1.22.3' and environment['packages']['sympy'] == '1.12' and
|
||||||
|
environment['Torch_imported_into_Brian'] is False and environment['author_precision'] == 'float64')
|
||||||
|
queue_audit = _read_json(cpu_dir/'queue-audit.json', used)
|
||||||
|
_check(checks, 'cpu.queue_observer_coverage', queue_audit['peek_calls'] == queue_audit['advance_calls'] == steps and
|
||||||
|
queue_audit['same_peek_object_returned'] is True and queue_audit['zero_weight_and_refractory_rejected_edges_retained'] is True)
|
||||||
|
_check(checks, 'cpu.sidecar_complete', cpu['summary']['APL_worker_exit_status'] == 0 and cpu['summary']['APL_worker_ticks'] == steps)
|
||||||
|
report.update(case=spec['name'], steps=steps, nodes=n, edges=edges, record_history=history,
|
||||||
|
total_spikes=len(gpu['state']['step']), active_neurons=int(np.count_nonzero(gpu['state']['counts'])),
|
||||||
|
requested=len(requested), accepted_requests=sum(row['accepted'] for row in gpu['requests']),
|
||||||
|
rejected_requests=sum(row['rejected'] for row in gpu['requests']),
|
||||||
|
arriving_edges=sum(row['count'] for row in gpu['queues']),
|
||||||
|
accepted_arriving_edges=sum(row['accepted_count'] for row in gpu['queues']),
|
||||||
|
apl_fast_edges_zeroed=mask_count, effective_weights_raw_sha256=expected_sha,
|
||||||
|
component_environment=gpu['component']['environment'],
|
||||||
|
limits=['APL Torch primitives are shared; original AST component validation is a separate required gate.',
|
||||||
|
'Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.',
|
||||||
|
'For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.',
|
||||||
|
'This is exact agreement for the declared trajectory, not physiological validity or learning.'])
|
||||||
|
except Exception as error:
|
||||||
|
report['error'] = {'type': type(error).__name__, 'message': str(error)}
|
||||||
|
return _finish(report, checks, differences, used, out_json)
|
||||||
|
|
||||||
|
|
||||||
|
def compare_gpu_repeats(first, second, out_json=None):
|
||||||
|
"""Repeat equality only; the first run's independent oracle gate is separate."""
|
||||||
|
first, second = Path(first), Path(second)
|
||||||
|
if out_json is not None:
|
||||||
|
require(not Path(out_json).exists(), 'Refusing existing repeat report')
|
||||||
|
checks, differences, used = {}, {}, set()
|
||||||
|
report = {'kind': 'fresh-GPU-run exact repeat comparison', 'first': str(first), 'second': str(second),
|
||||||
|
'pass_all': False, 'tolerance': None, 'signed_zero_included': True, 'timing_fields_compared': False,
|
||||||
|
'scope': 'Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()'}
|
||||||
|
try:
|
||||||
|
summary = _read_json(first/'summary.json', used)
|
||||||
|
n, edges, steps, name, history = (summary[key] for key in ('nodes', 'edges', 'steps', 'case', 'record_history'))
|
||||||
|
require(type(n) is int and type(edges) is int and type(steps) is int and n > 0 and edges > 0 and steps > 0 and
|
||||||
|
type(history) is bool and history == (n < 512), 'Invalid repeat dimensions')
|
||||||
|
left = _load_run(first, 'first_gpu', n, edges, steps, history, name, used, checks)
|
||||||
|
right = _load_run(second, 'second_gpu', n, edges, steps, history, name, used, checks)
|
||||||
|
_pair_outputs(left, right, checks, differences, n, steps, history)
|
||||||
|
stable = ('case', 'complete', 'pass_all', 'steps', 'completed_ticks', 'nodes', 'edges', 'precision',
|
||||||
|
'apl_precision', 'state_units', 'total_spikes', 'requested', 'accepted_requests', 'rejected_requests',
|
||||||
|
'arriving_edges', 'accepted_arriving_edges', 'counts_match_sparse_events', 'all_finite', 'record_history',
|
||||||
|
'apl_fast_edges_zeroed', 'kc_targets_present', 'effective_weights_raw_sha256', 'apl_schedule',
|
||||||
|
'apl_si_conversion', 'build', 'sealed_ae_backend_sha256', 'learning', 'input_sha256')
|
||||||
|
for key in stable:
|
||||||
|
_check(checks, 'summary.'+key, key in left['summary'] and key in right['summary'] and
|
||||||
|
left['summary'][key] == right['summary'][key])
|
||||||
|
if not checks['summary.'+key]:
|
||||||
|
differences['summary.'+key] = {'first': left['summary'].get(key), 'second': right['summary'].get(key)}
|
||||||
|
report.update(case=name, steps=steps, nodes=n, edges=edges, record_history=history,
|
||||||
|
total_spikes=len(left['state']['step']),
|
||||||
|
explicit_exclusions=['wall_seconds', 'diagnostic_simulation_seconds', 'build_or_cache_seconds',
|
||||||
|
'peak_allocated_vram_bytes', 'peak_reserved_vram_bytes'])
|
||||||
|
except Exception as error:
|
||||||
|
report['error'] = {'type': type(error).__name__, 'message': str(error)}
|
||||||
|
return _finish(report, checks, differences, used, out_json)
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"phase": "4AG-r2",
|
||||||
|
"name": "author-apl-lab-v2",
|
||||||
|
"execution_revision": "Preserve declared venv Python entry rather than resolving its symlink to system Python. No dynamics or inputs changed.",
|
||||||
|
"human_authorization": "允许独立新模型分支测试动力学假设",
|
||||||
|
"gpu_uuid": "GPU-79f3a85d-adce-7833-7003-6488140ca596",
|
||||||
|
"neurons": 166700,
|
||||||
|
"edges": 25582938,
|
||||||
|
"raw_weight_sum": 124177617,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"apl": {"tau_ms": 20.0, "gain": 0.01, "normalization": 1.0},
|
||||||
|
"hypothesis": "Author LIF plus unchanged legacy graded APL operator at end, after reset, unconditional KC g write. Mixed precision: h32 promoted to float64, then multiplied by float64 .001 SI, then subtracted. Not original author's APL model.",
|
||||||
|
"fixtures": ["zero", "pn_pulse", "kc_ref_boundary", "two_sources", "arrival_collision", "natural_request", "apl_only", "high_fanin"],
|
||||||
|
"fixture_repeats": 3,
|
||||||
|
"calibration": {"split": "calibration", "odor_count": 6, "modes": ["physiological", "matched_energy"], "seeds": [51101,51102,51103,51104,51105], "duration_ms": 100.0, "median_scope": "original frozen 12-odor panel", "full_oracle_probes": ["cal-physiological-00-s51101", "cal-matched_energy-00-s51101"], "repeat_first_seed_each_odor": true},
|
||||||
|
"gates": {"sparse_min_fraction": 0.03, "sparse_max_fraction": 0.09, "max_fraction_strict": 0.5, "min_fraction_strict": 0.0, "minimum_separable_odor_pairs": 3, "same_jaccard_gt_between": true, "between_euclidean_gt_within": true, "both_modes_required": true, "finite_required": true, "repeat_exact_required": true},
|
||||||
|
"training": false,
|
||||||
|
"heldout_dynamic_access": false,
|
||||||
|
"candidate_generation": false,
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"scope": "Semantic compatibility and fixed old CAL only. Shared-APL-component closed-loop Brian oracle plus independent arithmetic audit; never claim all-component independent CPU equivalence or learning success. No parameter/input/site/window selection from results."
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import hashlib
|
||||||
|
import importlib.util
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT=Path('/data/digital-drosophila')
|
||||||
|
MODEL=Path(__file__).resolve().parent
|
||||||
|
EXP=ROOT/'experiments/phase4ag-author-apl-r2'
|
||||||
|
AF_MODEL=ROOT/'models/male-cns-lif/author-fullgraph-lab-v1'
|
||||||
|
AF_EXP=ROOT/'experiments/phase4af-author-fullgraph'
|
||||||
|
AD_EXP=ROOT/'experiments/phase4ad-author-semantics'
|
||||||
|
CFG=json.loads((MODEL/'config.json').read_text(encoding='utf-8'))
|
||||||
|
|
||||||
|
def digest(path):
|
||||||
|
h=hashlib.sha256()
|
||||||
|
with Path(path).open('rb') as f:
|
||||||
|
for b in iter(lambda:f.read(8<<20),b''):h.update(b)
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
def save(path,value):
|
||||||
|
path=Path(path);path.parent.mkdir(parents=True,exist_ok=True)
|
||||||
|
with path.open('x',encoding='utf-8') as f:json.dump(value,f,indent=2,ensure_ascii=False,allow_nan=False);f.write('\n')
|
||||||
|
|
||||||
|
def sources():
|
||||||
|
return {p.name:digest(p) for p in sorted(MODEL.iterdir()) if p.is_file() and p.name not in ('manifest.json','checksums.sha256')}
|
||||||
|
|
||||||
|
def integrity():
|
||||||
|
spec=importlib.util.spec_from_file_location('frozen_af_context',AF_MODEL/'context.py')
|
||||||
|
mod=importlib.util.module_from_spec(spec);spec.loader.exec_module(mod)
|
||||||
|
result=mod.integrity()
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0,str(ROOT/'models/male-cns-lif/terminal-scope-diagnostic-v1'))
|
||||||
|
from diagnostic import manifest_check
|
||||||
|
for p in (AF_MODEL,AF_EXP,ROOT/'models/male-cns-lif/author-apl-lab-v1',ROOT/'experiments/phase4ag-author-apl'):
|
||||||
|
result[str(p.relative_to(ROOT))]=manifest_check(p,digest)
|
||||||
|
assert all(r['pass'] for r in result.values())
|
||||||
|
return result
|
||||||
|
|
||||||
|
def check():
|
||||||
|
p=json.loads((EXP/'protocol/preregistered.json').read_text())
|
||||||
|
assert p['sources']==sources(),'Source changed after preregistration'
|
||||||
|
for row in p['inputs']:assert digest(ROOT/row['path'])==row['sha256'],row['path']
|
||||||
|
for row in json.loads((EXP/'protocol/prepared-hashes.json').read_text()):
|
||||||
|
assert digest(EXP/row['path'])==row['sha256'],row['path']
|
||||||
|
return p
|
||||||
|
|
||||||
|
def budget():
|
||||||
|
size=sum(p.stat().st_size for p in EXP.rglob('*') if p.is_file())
|
||||||
|
assert size<CFG['output_budget_bytes'],'New output resource budget exceeded'
|
||||||
|
return size
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
"""Seal a completed gate or preserved failure; never claim learning."""
|
||||||
|
import json
|
||||||
|
from context import ROOT,MODEL,EXP,CFG,check,save,digest,integrity,budget
|
||||||
|
|
||||||
|
|
||||||
|
def seal(root):
|
||||||
|
assert not (root/'manifest.json').exists() and not (root/'checksums.sha256').exists()
|
||||||
|
rows=[dict(path=str(p.relative_to(root)),bytes=p.stat().st_size,sha256=digest(p))
|
||||||
|
for p in sorted(root.rglob('*')) if p.is_file() and '__pycache__' not in p.parts]
|
||||||
|
save(root/'manifest.json',dict(root=str(root),files=rows))
|
||||||
|
with (root/'checksums.sha256').open('x') as f:
|
||||||
|
for row in rows:f.write(row['sha256']+' '+row['path']+'\n')
|
||||||
|
f.write(digest(root/'manifest.json')+' manifest.json\n')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
from compare import compare,compare_gpu_repeats
|
||||||
|
check();budget();comparisons=[];repeats={};components={}
|
||||||
|
for p in sorted((EXP/'audit').glob('compare-*.json')):
|
||||||
|
name=p.stem[len('compare-'):]
|
||||||
|
actual=compare(EXP/'cases'/name,EXP/'gpu'/(name+'-r0'),EXP/'oracle'/name,None)
|
||||||
|
assert actual==json.loads(p.read_text()),'Changed raw closed-loop evidence: '+name
|
||||||
|
comparisons.append(dict(case=name,pass_all=actual['pass_all']))
|
||||||
|
for p in sorted((EXP/'audit').glob('repeat-*.json')):
|
||||||
|
name,repeat=p.stem[len('repeat-'):].rsplit('-r',1)
|
||||||
|
actual=compare_gpu_repeats(EXP/'gpu'/(name+'-r0'),EXP/'gpu'/f'{name}-r{repeat}',None)
|
||||||
|
assert actual==json.loads(p.read_text()),'Changed raw repeat evidence: '+name
|
||||||
|
repeats[f'{name}-r{repeat}']=actual['pass_all']
|
||||||
|
for p in (EXP/'component-audit').glob('*.json'):
|
||||||
|
result=json.loads(p.read_text())
|
||||||
|
components[p.stem]=result['pass_all']
|
||||||
|
for filename,sha in result.get('input_sha256',{}).items():
|
||||||
|
assert digest(EXP/'gpu'/(p.stem+'-r0')/filename)==sha
|
||||||
|
gates={}
|
||||||
|
for name in ('fixtures','probes','calibration'):
|
||||||
|
path=EXP/'audit'/(name+'-gate.json')
|
||||||
|
gates[name]=json.loads(path.read_text()) if path.exists() else None
|
||||||
|
calpath=EXP/'calibration/summary.json'
|
||||||
|
cal=json.loads(calpath.read_text()) if calpath.exists() else None
|
||||||
|
if cal is not None:
|
||||||
|
from calibration import summarize
|
||||||
|
assert summarize(out_json=None)==cal,'CAL raw evidence changed'
|
||||||
|
frozen=json.loads((EXP/'regression/frozen-five.json').read_text())
|
||||||
|
after=integrity();save(EXP/'regression/old-integrity-after.json',after)
|
||||||
|
stops=[dict(path=str(p.relative_to(EXP)),report=json.loads(p.read_text())) for p in sorted((EXP/'audit').glob('stopped-*.json'))]
|
||||||
|
expected_cases=CFG['fixtures']+CFG['calibration']['full_oracle_probes']
|
||||||
|
expected_repeats=[f'{name}-r{r}' for name in CFG['fixtures'] for r in range(1,CFG['fixture_repeats'])]
|
||||||
|
compared={x['case']:x['pass_all'] for x in comparisons}
|
||||||
|
missing=dict(comparisons=sorted(set(expected_cases)-set(compared)),
|
||||||
|
components=sorted(set(expected_cases)-set(components)),repeats=sorted(set(expected_repeats)-set(repeats)))
|
||||||
|
evidence_ok=(set(compared)==set(components)==set(expected_cases) and set(repeats)==set(expected_repeats) and
|
||||||
|
all(compared.values()) and all(components.values()) and all(repeats.values()))
|
||||||
|
numerical=evidence_ok and all(gates[x] is not None and gates[x]['pass_all'] for x in ('fixtures','probes'))
|
||||||
|
representation=bool(cal is not None and cal['pass_all'])
|
||||||
|
if numerical:status='PASS-FIXED-CAL-REPRESENTATION' if representation else 'FAIL-FIXED-CAL-REPRESENTATION' if cal is not None else 'INCOMPLETE-CAL-EXECUTION'
|
||||||
|
else:status='FAIL-NUMERICAL-OR-AUDIT-GATE' if any(not p for group in (compared,components,repeats) for p in group.values()) else 'INCOMPLETE-NUMERICAL-EXECUTION'
|
||||||
|
oldpass=bool(frozen['pass_all'] and all(r['pass'] for r in after.values()))
|
||||||
|
if not oldpass:status='FAIL-FROZEN-INTEGRITY-OR-REGRESSION'
|
||||||
|
measurements=[]
|
||||||
|
for p in sorted((EXP/'gpu').glob('*/summary.json')):
|
||||||
|
s=json.loads(p.read_text())
|
||||||
|
measurements.append({k:s[k] for k in ('case','total_spikes','accepted_requests','nodes','edges','diagnostic_simulation_seconds','peak_allocated_vram_bytes')})
|
||||||
|
result=dict(status=status,numerical_gate_pass=bool(numerical),fixed_CAL_representation_pass=representation,
|
||||||
|
gates=gates,closed_loop_comparisons=comparisons,component_results=components,repeat_results=repeats,
|
||||||
|
missing_numerical_evidence=missing,calibration=cal,stopped=stops,
|
||||||
|
old_frozen_integrity_and_five_reference_pass=oldpass,measurements=measurements,
|
||||||
|
unchanged_APL_parameters=CFG['apl'],author_LIF_precision='float64',legacy_APL_precision='float32',
|
||||||
|
explicit_hypothesis=CFG['hypothesis'],APL_nonKC_fast_edges_unreplaced=1212,
|
||||||
|
shared_APL_component_oracle_limitation=True,whole_brain_universal_equivalence_claim=False,
|
||||||
|
heldout_generalization_tested=False,formal_AB_tested=False,learning_achieved=False,candidate_generated=False,
|
||||||
|
payload_bytes_before_manifest=budget(),
|
||||||
|
next_gate='Independent seeds/novel-odor representation, then credit specificity; no learning promotion from CAL' if numerical and representation else
|
||||||
|
'Audit first failure in this explicitly declared hypothesis; no gain search, no heldout tuning, no conditioning')
|
||||||
|
save(EXP/'audit/final-status.json',result)
|
||||||
|
lines=['# Phase 4AG: author LIF + unchanged legacy graded APL','',f'Status: `{status}`.','',
|
||||||
|
f'Numerical closed-loop gate: {numerical}; original complete fixed six-CAL gate: {representation}.',
|
||||||
|
'The independent Brian LIF and candidate use independent state but share the APL arithmetic component. Original frozen APL AST replay and a float64 error audit are separately recorded.',
|
||||||
|
'Author LIF uses float64; APL retains float32, tau20ms/gain0.01/normalization1, full original matrices and order. No learning/parameter search.',
|
||||||
|
'The explicitly hypothesized unconditional end-APL write includes refractory KC. Original fast APL mask leaves1,212 non-KC edges unreplaced; this scope limitation was not silently fixed.',
|
||||||
|
f'Old checksums and five frozen reference trials: {oldpass}.',
|
||||||
|
f'Successfully compared cases: {comparisons}.',
|
||||||
|
'Detailed CAL, exact comparisons, component errors, event/request traces and execution exceptions are linked from audit/final-status.json.',
|
||||||
|
'Wall/VRAM here include per-tick CPU synchronization, IPC and hashes. They are diagnostic costs, not runtime-performance benchmarks.',
|
||||||
|
'No heldout dynamic outputs, formal A/B, learning, game, reward, decoder or new candidate.',
|
||||||
|
'Next gate: '+result['next_gate'],'']
|
||||||
|
with (EXP/'REPORT.md').open('x',encoding='utf-8') as f:f.write('\n'.join(lines))
|
||||||
|
check();seal(MODEL);seal(EXP);print(status,flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
"""Diagnostic author-float64 LIF plus frozen legacy-float32 APL overlay.
|
||||||
|
|
||||||
|
The sealed Phase 4AE CUDA operators are reused without modification. APL is
|
||||||
|
an explicitly mixed-precision engineering overlay, not an author-model claim.
|
||||||
|
All CUDA/CPU synchronization here is diagnostic; no performance claim is made.
|
||||||
|
"""
|
||||||
|
from functools import lru_cache
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
import types
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import torch
|
||||||
|
|
||||||
|
from legacy_apl_worker import LegacyAPL, N_NEURONS, file_sha256, array_sha256
|
||||||
|
|
||||||
|
|
||||||
|
SOURCE_ROOT = Path(__file__).resolve().parent
|
||||||
|
AE_MODEL = SOURCE_ROOT.parent / "author-runtime-lab-v1"
|
||||||
|
AF_MODEL = SOURCE_ROOT.parent / "author-fullgraph-lab-v1"
|
||||||
|
COEFFICIENT_NAMES = ("gd", "c0", "cg", "cv", "threshold", "reset", "seed_volt")
|
||||||
|
REQUEST_FIELDS = ("tick", "neuron_idx", "attempted", "accepted", "rejected")
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def write_json(path, value):
|
||||||
|
with Path(path).open("x", encoding="utf-8") as output:
|
||||||
|
json.dump(value, output, indent=2, allow_nan=False)
|
||||||
|
output.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def raw_hash(value, dtype):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value, dtype=dtype).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def load_source(path, name):
|
||||||
|
module = types.ModuleType(name)
|
||||||
|
module.__file__ = str(path)
|
||||||
|
exec(compile(Path(path).read_bytes(), str(path), "exec"), module.__dict__)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def sealed_backend():
|
||||||
|
return load_source(AE_MODEL / "gpu_backend.py", "phase4ag_sealed_ae_backend")
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=1)
|
||||||
|
def queue_function():
|
||||||
|
return load_source(AF_MODEL / "oracle_full.py", "phase4ag_sealed_af_queue").queue_summary
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=4)
|
||||||
|
def load_graph(graph_directory):
|
||||||
|
root = Path(graph_directory)
|
||||||
|
require(root.is_absolute(), "graph_dir must be absolute")
|
||||||
|
graph = {}
|
||||||
|
for name, dtype in (("nodes", np.int32), ("edge_id", np.int64), ("src", np.int32),
|
||||||
|
("dst", np.int32), ("signed_raw", np.int64), ("ptr", np.int64),
|
||||||
|
("weights", np.float64)):
|
||||||
|
value = np.load(root / (name + ".npy"), mmap_mode="r", allow_pickle=False)
|
||||||
|
require(value.dtype == dtype and value.ndim == 1, "Graph dtype/rank mismatch: " + name)
|
||||||
|
graph[name] = value
|
||||||
|
nodes, edges = graph["nodes"], graph["edge_id"]
|
||||||
|
n, e = len(nodes), len(edges)
|
||||||
|
require(0 < n <= N_NEURONS and bool(np.all((nodes >= 0) & (nodes < N_NEURONS))) and
|
||||||
|
bool(np.all(np.diff(nodes) > 0)), "Global node IDs must be sorted unique")
|
||||||
|
require(n < 512 or (n == N_NEURONS and np.array_equal(nodes, np.arange(N_NEURONS, dtype=np.int32))),
|
||||||
|
"Only small fixtures or the intact frozen full graph are permitted")
|
||||||
|
require(n != N_NEURONS or e == 25582938, "Full graph edge count changed")
|
||||||
|
for name in ("src", "dst", "signed_raw", "weights"):
|
||||||
|
require(graph[name].shape == (e,), "Graph edge array length mismatch: " + name)
|
||||||
|
ptr = graph["ptr"]
|
||||||
|
require(ptr.shape == (n + 1,) and ptr[0] == 0 and ptr[-1] == e and
|
||||||
|
bool(np.all(np.diff(ptr) >= 0)), "Invalid graph CSR")
|
||||||
|
require(np.array_equal(graph["src"], np.repeat(np.arange(n, dtype=np.int32), np.diff(ptr))),
|
||||||
|
"Source order does not match CSR")
|
||||||
|
# Global edge IDs need not equal local row indices in a fixture.
|
||||||
|
for start in range(0, e, 1 << 20):
|
||||||
|
stop = min(start + (1 << 20), e)
|
||||||
|
require(bool(np.all((graph["dst"][start:stop] >= 0) & (graph["dst"][start:stop] < n))),
|
||||||
|
"Local destination out of range")
|
||||||
|
require(bool(np.isfinite(graph["weights"][start:stop]).all()), "Nonfinite base SI weights")
|
||||||
|
require(np.array_equal(np.sign(graph["weights"][start:stop]), np.sign(graph["signed_raw"][start:stop])),
|
||||||
|
"Base weight sign/zero pattern differs from frozen raw contacts")
|
||||||
|
lo = max(0, start - 1)
|
||||||
|
require(bool(np.all(edges[start:stop] >= 0)) and bool(np.all(np.diff(edges[lo:stop]) > 0)),
|
||||||
|
"Global edge IDs must retain canonical increasing source/edge order")
|
||||||
|
return graph
|
||||||
|
|
||||||
|
|
||||||
|
def load_inputs(case_dir):
|
||||||
|
spec = json.loads((case_dir / "spec.json").read_text(encoding="utf-8"))
|
||||||
|
for name in ("name", "steps", "dt_ms", "duration_ms", "model", "graph_dir", "apl",
|
||||||
|
"apl_bundle_dir", "coefficients_path", "record_history"):
|
||||||
|
require(name in spec, "Missing case field: " + name)
|
||||||
|
steps = spec["steps"]
|
||||||
|
require(type(steps) is int and 0 < steps <= 1000 and float(spec["dt_ms"]) == .1 and
|
||||||
|
float(spec["duration_ms"]) == steps * .1, "Unexpected steps/dt/duration")
|
||||||
|
require(type(spec["record_history"]) is bool, "record_history must be Boolean")
|
||||||
|
require(spec["apl"] == {"tau_ms": 20, "gain": .01, "normalization": 1}, "Frozen APL parameters changed")
|
||||||
|
for name in ("graph_dir", "apl_bundle_dir", "coefficients_path"):
|
||||||
|
require(Path(spec[name]).is_absolute(), "Input path must be absolute: " + name)
|
||||||
|
model = spec["model"]
|
||||||
|
for name in ("resting_potential_mv", "threshold_mv", "reset_potential_mv", "synaptic_delay_ms",
|
||||||
|
"refractory_ms", "w_syn_mv_per_anatomical_synapse"):
|
||||||
|
require(name in model and math.isfinite(float(model[name])), "Invalid model field: " + name)
|
||||||
|
require(float(model["synaptic_delay_ms"]) == 1.8 and float(model["refractory_ms"]) == 2.2 and
|
||||||
|
float(model["w_syn_mv_per_anatomical_synapse"]) == .275, "Frozen delay/ref/W_syn changed")
|
||||||
|
coeff = json.loads(Path(spec["coefficients_path"]).read_text(encoding="utf-8"))
|
||||||
|
for name in COEFFICIENT_NAMES:
|
||||||
|
require(name in coeff and math.isfinite(float(coeff[name])), "Invalid author coefficient: " + name)
|
||||||
|
require(coeff["threshold"] == float(model["threshold_mv"]) * .001 and
|
||||||
|
coeff["reset"] == float(model["reset_potential_mv"]) * .001, "Coefficient threshold/reset mismatch")
|
||||||
|
graph = load_graph(str(Path(spec["graph_dir"]).resolve()))
|
||||||
|
n = len(graph["nodes"])
|
||||||
|
require(spec["record_history"] == (n < 512), "Fixtures need dense history; full graph must not duplicate dense histories")
|
||||||
|
with np.load(case_dir / "requests.npz", allow_pickle=False) as source:
|
||||||
|
require(set(source.files) == {"tick", "neuron_idx"}, "Request sparse schema changed")
|
||||||
|
ticks, requested = source["tick"].copy(), source["neuron_idx"].copy()
|
||||||
|
require(ticks.dtype == np.int32 and requested.dtype == np.int32 and ticks.ndim == 1 and
|
||||||
|
ticks.shape == requested.shape, "Invalid sparse request dtype/shape")
|
||||||
|
require(bool(np.all((ticks >= 0) & (ticks < steps))), "Request tick outside trial")
|
||||||
|
if len(ticks) > 1:
|
||||||
|
require(bool(np.all((ticks[1:] > ticks[:-1]) |
|
||||||
|
((ticks[1:] == ticks[:-1]) & (requested[1:] > requested[:-1])))),
|
||||||
|
"Requests must be sorted unique by tick/global neuron")
|
||||||
|
local = np.searchsorted(graph["nodes"], requested)
|
||||||
|
require(bool(np.all(local < n)) and np.array_equal(graph["nodes"][local], requested),
|
||||||
|
"Requested neuron absent from graph")
|
||||||
|
initial = {"initial_v_mv": np.full(n, float(model["resting_potential_mv"]), dtype=np.float64),
|
||||||
|
"initial_g_mv": np.zeros(n, dtype=np.float64)}
|
||||||
|
initial_path = case_dir / "arrays.npz"
|
||||||
|
if initial_path.exists():
|
||||||
|
with np.load(initial_path, allow_pickle=False) as source:
|
||||||
|
require(set(source.files).issubset(initial), "Unexpected initial-state array")
|
||||||
|
for name in source.files:
|
||||||
|
value = source[name]
|
||||||
|
require(value.dtype == np.float64 and value.shape == (n,) and bool(np.isfinite(value).all()),
|
||||||
|
"Invalid initial state: " + name)
|
||||||
|
initial[name] = value.copy()
|
||||||
|
return spec, graph, coeff, ticks, requested, local, initial
|
||||||
|
|
||||||
|
|
||||||
|
def new_array(path, dtype, shape):
|
||||||
|
require(not Path(path).exists(), "Refusing existing output: " + str(path))
|
||||||
|
return np.lib.format.open_memmap(path, mode="w+", dtype=dtype, shape=shape)
|
||||||
|
|
||||||
|
|
||||||
|
def run_gpu(case_dir, out_dir, build_root):
|
||||||
|
"""Run fresh candidate state; never consume oracle/candidate APL traces.
|
||||||
|
|
||||||
|
pass_all denotes internal recording/finite integrity only. Independent
|
||||||
|
comparison and the original complete representation gate are separate.
|
||||||
|
"""
|
||||||
|
case_dir, out_dir = Path(case_dir), Path(out_dir)
|
||||||
|
require(not out_dir.exists(), "Refusing existing output directory: " + str(out_dir))
|
||||||
|
out_dir.mkdir(parents=True, exist_ok=False)
|
||||||
|
start, tick, completed = time.perf_counter(), -1, 0
|
||||||
|
maps = {}
|
||||||
|
try:
|
||||||
|
spec, graph, coeff, request_ticks, request_nodes, request_local, initial = load_inputs(case_dir)
|
||||||
|
require(torch.cuda.is_available() and torch.cuda.device_count() == 1 and
|
||||||
|
"4090" in torch.cuda.get_device_name(), "Only the declared single visible RTX4090 is permitted")
|
||||||
|
ext, build = sealed_backend().build_extension(build_root)
|
||||||
|
build_done = time.perf_counter()
|
||||||
|
apl = LegacyAPL(spec["apl_bundle_dir"], spec["dt_ms"])
|
||||||
|
write_json(out_dir / "apl-component.json", apl.metadata)
|
||||||
|
device = apl.device
|
||||||
|
torch.cuda.reset_peak_memory_stats(device)
|
||||||
|
n, e, steps = len(graph["nodes"]), len(graph["edge_id"]), spec["steps"]
|
||||||
|
|
||||||
|
def upload(value, dtype):
|
||||||
|
return torch.from_numpy(np.array(value, copy=True, order="C")).to(device=device, dtype=dtype).contiguous()
|
||||||
|
|
||||||
|
indptr, dst = upload(graph["ptr"], torch.int64), upload(graph["dst"], torch.int32)
|
||||||
|
global_nodes_gpu = upload(graph["nodes"], torch.int64)
|
||||||
|
base_weights = upload(graph["weights"], torch.float64)
|
||||||
|
weights = base_weights.clone()
|
||||||
|
del base_weights
|
||||||
|
local_apl = np.flatnonzero(np.isin(graph["nodes"], apl.apl_globals)).astype(np.int64)
|
||||||
|
apl_out_mask = np.isin(graph["src"], local_apl)
|
||||||
|
if bool(np.any(apl_out_mask)):
|
||||||
|
weights[upload(apl_out_mask, torch.bool)] = 0.0
|
||||||
|
effective_hash = hashlib.sha256()
|
||||||
|
for offset in range(0, e, 1 << 20):
|
||||||
|
effective_hash.update(weights[offset:offset + (1 << 20)].cpu().numpy().astype("<f8", copy=False).tobytes())
|
||||||
|
common_kc, local_kc, full_kc = np.intersect1d(graph["nodes"], apl.kc_globals, assume_unique=True, return_indices=True)
|
||||||
|
kc_local_gpu, kc_full_gpu = upload(local_kc, torch.int64), upload(full_kc, torch.int64)
|
||||||
|
v = upload(initial["initial_v_mv"] * .001, torch.float64)
|
||||||
|
g = upload(initial["initial_g_mv"] * .001, torch.float64)
|
||||||
|
ref = torch.zeros(n, device=device, dtype=torch.int32)
|
||||||
|
counts = torch.zeros(n, device=device, dtype=torch.int32)
|
||||||
|
requests = torch.zeros(n, device=device, dtype=torch.uint8)
|
||||||
|
ring = torch.zeros((19, n), device=device, dtype=torch.uint8)
|
||||||
|
for name, width in (("drive", 2), ("state", 2), ("inhibition", 4064)):
|
||||||
|
maps["apl_" + name] = new_array(out_dir / ("apl-" + name + ".float32.npy"), np.float32, (steps, width))
|
||||||
|
if spec["record_history"]:
|
||||||
|
for name, dtype in (("v", np.float64), ("g", np.float64), ("ref", np.int32)):
|
||||||
|
maps[name] = new_array(out_dir / (name + "-history." + np.dtype(dtype).name + ".npy"), dtype, (steps, n))
|
||||||
|
maps["pre_" + name] = new_array(out_dir / ("preAPL-" + name + "." + np.dtype(dtype).name + ".npy"), dtype, (steps, n))
|
||||||
|
event_steps, event_nodes = [], []
|
||||||
|
accepted_requests_total, due_total, accepted_due_total = 0, 0, 0
|
||||||
|
queue_summary = queue_function()
|
||||||
|
simulation_start = time.perf_counter()
|
||||||
|
with (out_dir / "queue.jsonl").open("x", encoding="utf-8", buffering=1) as queue_output, \
|
||||||
|
(out_dir / "tick-state-hashes.jsonl").open("x", encoding="utf-8", buffering=1) as hash_output, \
|
||||||
|
(out_dir / "requests.csv").open("x", encoding="utf-8", newline="", buffering=1) as request_output:
|
||||||
|
writer = csv.DictWriter(request_output, fieldnames=REQUEST_FIELDS)
|
||||||
|
writer.writeheader()
|
||||||
|
for tick in range(steps):
|
||||||
|
requests.zero_()
|
||||||
|
begin, end = np.searchsorted(request_ticks, (tick, tick + 1))
|
||||||
|
if end > begin:
|
||||||
|
requested_local_gpu = upload(request_local[begin:end], torch.int64)
|
||||||
|
requests[requested_local_gpu] = 1
|
||||||
|
accepted = (ref[requested_local_gpu] <= 1).to(torch.uint8).cpu().numpy()
|
||||||
|
accepted_requests_total += int(accepted.sum())
|
||||||
|
writer.writerows({"tick": tick, "neuron_idx": int(node), "attempted": 1,
|
||||||
|
"accepted": int(ok), "rejected": 1 - int(ok)}
|
||||||
|
for node, ok in zip(request_nodes[begin:end], accepted))
|
||||||
|
spikes = ring[tick % 19]
|
||||||
|
ext.state_step(v, g, ref, requests, spikes, counts,
|
||||||
|
*[float(coeff[name]) for name in COEFFICIENT_NAMES], 22)
|
||||||
|
expanded_global = np.empty(0, dtype=np.int64)
|
||||||
|
accepted_cpu = np.empty(0, dtype=np.uint8)
|
||||||
|
if tick >= 18:
|
||||||
|
due = ring[(tick - 18) % 19]
|
||||||
|
sources = torch.nonzero(due, as_tuple=False).flatten().contiguous()
|
||||||
|
if sources.numel():
|
||||||
|
degrees = indptr[sources + 1] - indptr[sources]
|
||||||
|
offsets = (torch.cumsum(degrees, dim=0) - degrees).contiguous()
|
||||||
|
edge_count = int(degrees.sum().item())
|
||||||
|
expanded = torch.empty(edge_count, device=device, dtype=torch.int64)
|
||||||
|
ext.fill_edges(indptr, sources, offsets, expanded)
|
||||||
|
if edge_count:
|
||||||
|
destination = dst[expanded]
|
||||||
|
# Actual active fanout order, BEFORE stable target grouping.
|
||||||
|
expanded_global = graph["edge_id"][expanded.cpu().numpy()].copy()
|
||||||
|
accepted_cpu = (ref[destination.long()] == 0).to(torch.uint8).cpu().numpy().copy()
|
||||||
|
order = torch.argsort(destination, stable=True)
|
||||||
|
ordered_edges, ordered_targets = expanded[order].contiguous(), destination[order]
|
||||||
|
boundary = torch.ones(edge_count, device=device, dtype=torch.bool)
|
||||||
|
boundary[1:] = ordered_targets[1:] != ordered_targets[:-1]
|
||||||
|
starts = torch.nonzero(boundary, as_tuple=False).flatten().contiguous()
|
||||||
|
targets = ordered_targets[starts].contiguous()
|
||||||
|
ext.apply_arrivals(ordered_edges, starts, targets, weights, g, ref)
|
||||||
|
queue = queue_summary(tick, expanded_global, accepted_cpu)
|
||||||
|
queue_output.write(json.dumps(queue, allow_nan=False) + "\n")
|
||||||
|
due_total += queue["count"]
|
||||||
|
accepted_due_total += queue["accepted_count"]
|
||||||
|
if spec["record_history"]:
|
||||||
|
for name, value in (("v", v), ("g", g), ("ref", ref)):
|
||||||
|
maps["pre_" + name][tick] = value.cpu().numpy()
|
||||||
|
if n == N_NEURONS:
|
||||||
|
full_spikes = spikes
|
||||||
|
else:
|
||||||
|
apl.spikes.zero_()
|
||||||
|
apl.spikes[global_nodes_gpu] = spikes
|
||||||
|
full_spikes = apl.spikes
|
||||||
|
drive, apl_state, h = apl.advance(full_spikes)
|
||||||
|
# Mixed precision contract: widen f32 h EXACTLY, THEN multiply
|
||||||
|
# in f64, THEN subtract in f64. Do not guard refractory KCs.
|
||||||
|
delta_si = h[kc_full_gpu].to(torch.float64) * 0.001
|
||||||
|
g[kc_local_gpu] = g[kc_local_gpu] - delta_si
|
||||||
|
apl_cpu = {"drive": drive.cpu().numpy().copy(), "state": apl_state.cpu().numpy().copy(),
|
||||||
|
"inhibition": h.cpu().numpy().copy()}
|
||||||
|
for name, value in apl_cpu.items():
|
||||||
|
maps["apl_" + name][tick] = value
|
||||||
|
actual = {"v": v.cpu().numpy().copy(), "g": g.cpu().numpy().copy(),
|
||||||
|
"ref": ref.cpu().numpy().copy()}
|
||||||
|
finite = all(bool(np.isfinite(value).all()) for value in list(actual.values()) + list(apl_cpu.values()))
|
||||||
|
row = {"tick": tick, **{name + "_sha256": raw_hash(value, "<i4" if name == "ref" else "<f8")
|
||||||
|
for name, value in actual.items()}}
|
||||||
|
hash_output.write(json.dumps(row, allow_nan=False) + "\n")
|
||||||
|
if spec["record_history"]:
|
||||||
|
for name, value in actual.items():
|
||||||
|
maps[name][tick] = value
|
||||||
|
fired_local = torch.nonzero(spikes, as_tuple=False).flatten().cpu().numpy()
|
||||||
|
if len(fired_local):
|
||||||
|
event_steps.append(np.full(len(fired_local), tick, dtype=np.int32))
|
||||||
|
event_nodes.append(graph["nodes"][fired_local].copy())
|
||||||
|
completed += 1
|
||||||
|
if not finite:
|
||||||
|
with (out_dir / "first-failure-state.npz").open("xb") as target:
|
||||||
|
np.savez_compressed(target, tick=np.array(tick, dtype=np.int32), **actual,
|
||||||
|
**{"apl_" + name: value for name, value in apl_cpu.items()})
|
||||||
|
require(False, "Nonfinite state; first failure saved")
|
||||||
|
torch.cuda.synchronize(device)
|
||||||
|
|
||||||
|
def joined(values):
|
||||||
|
return np.concatenate(values).astype(np.int32, copy=False) if values else np.empty(0, dtype=np.int32)
|
||||||
|
|
||||||
|
state = {"step": joined(event_steps), "neuron_idx": joined(event_nodes), "counts": counts.cpu().numpy(),
|
||||||
|
"v": v.cpu().numpy(), "g": g.cpu().numpy(), "ref": ref.cpu().numpy()}
|
||||||
|
with (out_dir / "state.npz").open("xb") as target:
|
||||||
|
np.savez_compressed(target, **state)
|
||||||
|
event_locals = np.searchsorted(graph["nodes"], state["neuron_idx"])
|
||||||
|
counts_exact = np.array_equal(np.bincount(event_locals, minlength=n), state["counts"])
|
||||||
|
require(counts_exact and completed == steps, "Sparse events/counts/completed ticks mismatch")
|
||||||
|
for value in maps.values():
|
||||||
|
value.flush()
|
||||||
|
summary = {"case": spec["name"], "complete": True, "pass_all": True,
|
||||||
|
"pass_all_scope": "internal finite/recording/event-count integrity only; independent equivalence not claimed",
|
||||||
|
"steps": steps, "completed_ticks": completed, "nodes": n, "edges": e, "precision": "float64",
|
||||||
|
"apl_precision": "float32", "state_units": "SI volts", "total_spikes": len(state["step"]),
|
||||||
|
"requested": len(request_nodes), "accepted_requests": accepted_requests_total,
|
||||||
|
"rejected_requests": len(request_nodes) - accepted_requests_total,
|
||||||
|
"arriving_edges": due_total, "accepted_arriving_edges": accepted_due_total,
|
||||||
|
"counts_match_sparse_events": bool(counts_exact), "all_finite": True,
|
||||||
|
"record_history": spec["record_history"], "apl_fast_edges_zeroed": int(apl_out_mask.sum()),
|
||||||
|
"kc_targets_present": len(common_kc), "effective_weights_raw_sha256": effective_hash.hexdigest(),
|
||||||
|
"apl_component": apl.metadata, "apl_schedule": "end, after threshold/reset and guarded arrivals, unconditional all KC",
|
||||||
|
"apl_si_conversion": "h32 -> float64 -> multiply float64 0.001 -> separate float64 subtraction",
|
||||||
|
"build": build, "sealed_ae_backend_sha256": file_sha256(AE_MODEL / "gpu_backend.py"),
|
||||||
|
"shared_apl_component_oracle_limitation": True, "oracle_validation_claim": False,
|
||||||
|
"learning": False, "performance_runtime_claim": False, "cpu_sync_each_tick": True,
|
||||||
|
"build_or_cache_seconds": build_done - start,
|
||||||
|
"diagnostic_simulation_seconds": time.perf_counter() - simulation_start,
|
||||||
|
"wall_seconds": time.perf_counter() - start,
|
||||||
|
"peak_allocated_vram_bytes": int(torch.cuda.max_memory_allocated(device)),
|
||||||
|
"peak_reserved_vram_bytes": int(torch.cuda.max_memory_reserved(device)),
|
||||||
|
"input_sha256": {"spec.json": file_sha256(case_dir / "spec.json"),
|
||||||
|
"requests.npz": file_sha256(case_dir / "requests.npz"),
|
||||||
|
"base_weights.npy": file_sha256(Path(spec["graph_dir"]) / "weights.npy"),
|
||||||
|
"coefficients.json": file_sha256(spec["coefficients_path"])}}
|
||||||
|
if (case_dir / "arrays.npz").exists():
|
||||||
|
summary["input_sha256"]["arrays.npz"] = file_sha256(case_dir / "arrays.npz")
|
||||||
|
write_json(out_dir / "summary.json", summary)
|
||||||
|
return summary
|
||||||
|
except Exception as error:
|
||||||
|
for value in maps.values():
|
||||||
|
value.flush()
|
||||||
|
write_json(out_dir / "error.json", {"complete": False, "pass_all": False,
|
||||||
|
"tick_in_progress": tick, "completed_ticks": completed,
|
||||||
|
"type": type(error).__name__, "message": str(error), "traceback": traceback.format_exc()})
|
||||||
|
raise
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
"""Frozen eager Torch float32 APL component and binary oracle sidecar.
|
||||||
|
|
||||||
|
This is the Phase 4P operator sequence, not an author-neuron implementation.
|
||||||
|
No precision/determinism flags are changed here. The full matrix dimensions
|
||||||
|
are retained even when the caller simulates a small neuronal fixture.
|
||||||
|
"""
|
||||||
|
import argparse
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import torch
|
||||||
|
|
||||||
|
|
||||||
|
PROTOCOL = "phase4ag-apl-v1"
|
||||||
|
N_NEURONS, N_APL, N_KC = 166700, 2, 4064
|
||||||
|
BUNDLE_FILES = ("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")
|
||||||
|
FRAME = struct.Struct("<qQ")
|
||||||
|
PAYLOAD_BYTES = (N_APL + N_APL + N_KC) * 4
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def file_sha256(path):
|
||||||
|
digest = hashlib.sha256()
|
||||||
|
with Path(path).open("rb") as stream:
|
||||||
|
for block in iter(lambda: stream.read(8 << 20), b""):
|
||||||
|
digest.update(block)
|
||||||
|
return digest.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def array_sha256(value):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def environment_metadata():
|
||||||
|
device = torch.cuda.current_device()
|
||||||
|
return {"torch": str(torch.__version__), "numpy": str(np.__version__),
|
||||||
|
"cuda": torch.version.cuda, "cudnn": torch.backends.cudnn.version(),
|
||||||
|
"device_name": torch.cuda.get_device_name(device), "device_index": device,
|
||||||
|
"device_capability": list(torch.cuda.get_device_capability(device)),
|
||||||
|
"deterministic_algorithms": torch.are_deterministic_algorithms_enabled(),
|
||||||
|
"cudnn_deterministic": torch.backends.cudnn.deterministic,
|
||||||
|
"cudnn_benchmark": torch.backends.cudnn.benchmark,
|
||||||
|
"cuda_matmul_allow_tf32": torch.backends.cuda.matmul.allow_tf32,
|
||||||
|
"cudnn_allow_tf32": torch.backends.cudnn.allow_tf32,
|
||||||
|
"float32_matmul_precision": torch.get_float32_matmul_precision(),
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": os.environ.get("CUBLAS_WORKSPACE_CONFIG"),
|
||||||
|
"precision_configuration_changed_by_component": False}
|
||||||
|
|
||||||
|
|
||||||
|
class LegacyAPL:
|
||||||
|
"""Independent zero-initialized APL state with original full-width matrices."""
|
||||||
|
|
||||||
|
def __init__(self, bundle_dir, dt_ms):
|
||||||
|
require(float(dt_ms) == 0.1, "Only frozen dt_ms=0.1 is allowed")
|
||||||
|
require(torch.cuda.is_available(), "CUDA is required for the legacy Torch component")
|
||||||
|
self.bundle_dir = Path(bundle_dir)
|
||||||
|
expected = {"input_matrix.npy": (np.float32, (N_APL, N_NEURONS)),
|
||||||
|
"output_matrix.npy": (np.float32, (N_APL, N_KC)),
|
||||||
|
"kc_globals.npy": (np.int32, (N_KC,)),
|
||||||
|
"apl_globals.npy": (np.int32, (N_APL,))}
|
||||||
|
arrays = {}
|
||||||
|
for name, (dtype, shape) in expected.items():
|
||||||
|
value = np.load(self.bundle_dir / name, allow_pickle=False)
|
||||||
|
require(value.dtype == dtype and value.shape == shape and value.flags.c_contiguous,
|
||||||
|
"APL bundle dtype/shape/layout mismatch: " + name)
|
||||||
|
require(bool(np.isfinite(value).all()), "Nonfinite APL bundle: " + name)
|
||||||
|
arrays[name] = value
|
||||||
|
for name in ("kc_globals.npy", "apl_globals.npy"):
|
||||||
|
ids = arrays[name]
|
||||||
|
require(bool(np.all((ids >= 0) & (ids < N_NEURONS))) and
|
||||||
|
bool(np.all(np.diff(ids) > 0)), "APL/KC globals must be sorted unique: " + name)
|
||||||
|
require(not np.intersect1d(arrays["kc_globals.npy"], arrays["apl_globals.npy"]).size,
|
||||||
|
"APL and KC identities overlap")
|
||||||
|
require(bool(np.all(arrays["input_matrix.npy"] >= 0)) and
|
||||||
|
bool(np.all(arrays["output_matrix.npy"] >= 0)), "APL raw-contact matrices must be nonnegative")
|
||||||
|
self.device = torch.device("cuda", torch.cuda.current_device())
|
||||||
|
self.input_gpu = torch.from_numpy(arrays["input_matrix.npy"].copy()).to(self.device)
|
||||||
|
self.output_gpu = torch.from_numpy(arrays["output_matrix.npy"].copy()).to(self.device)
|
||||||
|
self.kc_globals = arrays["kc_globals.npy"].copy()
|
||||||
|
self.apl_globals = arrays["apl_globals.npy"].copy()
|
||||||
|
self.state = torch.zeros(N_APL, dtype=torch.float32, device=self.device)
|
||||||
|
self.spikes = torch.zeros(N_NEURONS, dtype=torch.uint8, device=self.device)
|
||||||
|
self.decay = np.float32(math.exp(-float(dt_ms) / 20.0))
|
||||||
|
self.gain = np.float32(0.01)
|
||||||
|
self.metadata = {"ok": True, "protocol": PROTOCOL, "n_neurons": N_NEURONS,
|
||||||
|
"n_apl": N_APL, "n_kc": N_KC, "dt_ms": float(dt_ms),
|
||||||
|
"files_sha256": {name: file_sha256(self.bundle_dir / name) for name in BUNDLE_FILES},
|
||||||
|
"array_sha256": {name: array_sha256(value) for name, value in arrays.items()},
|
||||||
|
"decay_f32_bits": f"{int(self.decay.view(np.uint32)):08x}",
|
||||||
|
"gain_f32_bits": f"{int(self.gain.view(np.uint32)):08x}",
|
||||||
|
"environment": environment_metadata(),
|
||||||
|
"operator_sequence": "state.mul_(decay32); drive=mv(I32,spikes32); state.add_(drive); h=matmul(state,O32)*gain32",
|
||||||
|
"h_units": "legacy mV", "initial_state": "float32 zeros"}
|
||||||
|
|
||||||
|
@torch.no_grad()
|
||||||
|
def advance(self, spikes_u8):
|
||||||
|
require(spikes_u8.device == self.device and spikes_u8.dtype == torch.uint8 and
|
||||||
|
tuple(spikes_u8.shape) == (N_NEURONS,) and spikes_u8.is_contiguous(),
|
||||||
|
"APL expects full-width contiguous CUDA uint8 spikes")
|
||||||
|
# Preserve separate eager operations, including Python evaluation order
|
||||||
|
# in the frozen state.mul_(...).add_(torch.mv(...)) expression.
|
||||||
|
self.state.mul_(float(self.decay))
|
||||||
|
drive = torch.mv(self.input_gpu, spikes_u8.to(torch.float32))
|
||||||
|
self.state.add_(drive)
|
||||||
|
h = torch.matmul(self.state, self.output_gpu) * self.gain
|
||||||
|
return drive, self.state, h
|
||||||
|
|
||||||
|
def advance_global_fired(self, fired):
|
||||||
|
require(fired.dtype == np.int32 and fired.ndim == 1, "Global spikes must be int32 vector")
|
||||||
|
require(bool(np.all((fired >= 0) & (fired < N_NEURONS))) and
|
||||||
|
bool(np.all(np.diff(fired) > 0)), "Global spikes must be sorted unique and in range")
|
||||||
|
self.spikes.zero_()
|
||||||
|
if fired.size:
|
||||||
|
indices = torch.from_numpy(fired.copy()).to(device=self.device, dtype=torch.int64)
|
||||||
|
self.spikes[indices] = 1
|
||||||
|
return self.advance(self.spikes)
|
||||||
|
|
||||||
|
|
||||||
|
def read_exact(stream, count, boundary_eof=False):
|
||||||
|
result = bytearray()
|
||||||
|
while len(result) < count:
|
||||||
|
block = stream.read(count - len(result))
|
||||||
|
if not block:
|
||||||
|
if boundary_eof and not result:
|
||||||
|
return None
|
||||||
|
raise EOFError("Truncated APL request frame")
|
||||||
|
result.extend(block)
|
||||||
|
return bytes(result)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--bundle-dir", required=True)
|
||||||
|
parser.add_argument("--dt-ms", required=True, type=float)
|
||||||
|
args = parser.parse_args()
|
||||||
|
# stdout is exclusively the handshake line and binary response frames.
|
||||||
|
output, source = sys.stdout.buffer, sys.stdin.buffer
|
||||||
|
component = LegacyAPL(args.bundle_dir, args.dt_ms)
|
||||||
|
output.write((json.dumps(component.metadata, allow_nan=False) + "\n").encode("utf-8"))
|
||||||
|
output.flush()
|
||||||
|
expected_tick = 0
|
||||||
|
while True:
|
||||||
|
header = read_exact(source, FRAME.size, boundary_eof=True)
|
||||||
|
if header is None:
|
||||||
|
return
|
||||||
|
tick, count = FRAME.unpack(header)
|
||||||
|
require(tick == expected_tick and count <= N_NEURONS, "Invalid APL request tick/count")
|
||||||
|
fired = np.frombuffer(read_exact(source, count * 4), dtype="<i4").copy()
|
||||||
|
drive, state, h = component.advance_global_fired(fired)
|
||||||
|
arrays = [value.detach().cpu().numpy().astype("<f4", copy=False) for value in (drive, state, h)]
|
||||||
|
require(all(bool(np.isfinite(value).all()) for value in arrays), "Nonfinite APL output")
|
||||||
|
output.write(FRAME.pack(tick, PAYLOAD_BYTES))
|
||||||
|
for value in arrays:
|
||||||
|
output.write(value.tobytes())
|
||||||
|
output.flush()
|
||||||
|
expected_tick += 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"root": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2",
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "PROTOCOL.md",
|
||||||
|
"bytes": 5583,
|
||||||
|
"sha256": "49f53924f758317bfcbd2b53cab9b8b785121eb99f3234a8343c9b483c5701d8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "calibration.py",
|
||||||
|
"bytes": 25414,
|
||||||
|
"sha256": "edb9cb2d890471fd07afd88c959ef3540b0cd40af490fac3f26396b5e7f5bf9c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "compare.py",
|
||||||
|
"bytes": 33632,
|
||||||
|
"sha256": "6e1616b086f667fa4e4b5087f500f8080281977ca9922e7b055acfddd2003bd5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "config.json",
|
||||||
|
"bytes": 1994,
|
||||||
|
"sha256": "a8bafb9deec49d918976f2836d977ef9f13c26a6fb7f70e015879e29cf986c9a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "context.py",
|
||||||
|
"bytes": 2134,
|
||||||
|
"sha256": "274eb13ccf38dbbc5c7f14d9d642130eb0f69072d91a090f208c30c27f87dd2b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "finalize.py",
|
||||||
|
"bytes": 6747,
|
||||||
|
"sha256": "b6e3c67e668a971b544df32d76435ab5e537061b9fc2e8d9dedb5d2a726f5782"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "gpu_apl.py",
|
||||||
|
"bytes": 21206,
|
||||||
|
"sha256": "69f5d893f47dafff4ef7c3186c3df0b9014666b32c8f4e943b57016bec92b18a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "legacy_apl_worker.py",
|
||||||
|
"bytes": 8158,
|
||||||
|
"sha256": "21ceec65fe42581dc55872010e0025d660e80358905f1cf4df1dadf341a3b291"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "oracle_apl.py",
|
||||||
|
"bytes": 46236,
|
||||||
|
"sha256": "357a7d3debb5abc34a8714c0233b456547a154d9d5855d28661b4f01019a80ea"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "prepare.py",
|
||||||
|
"bytes": 15297,
|
||||||
|
"sha256": "e9328567753e144fc315491970f7e02af13725b93f35e4d4b97f7c4c48ce3338"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "run_case.py",
|
||||||
|
"bytes": 2116,
|
||||||
|
"sha256": "afbe6d5a37c29bda66d38c470093584130d1852e67881c681662aec3c76b33c7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "run_suite.py",
|
||||||
|
"bytes": 3700,
|
||||||
|
"sha256": "84c681030b0032119b5392d0c3f3c136a9c6b0d133eb548c40791a10bbbb8b63"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "test_calibration.py",
|
||||||
|
"bytes": 8127,
|
||||||
|
"sha256": "bab3136eecbc5bb09a985d715844ee845cb72b07930ce376bfb39be33bd1845a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "test_protocol.py",
|
||||||
|
"bytes": 11764,
|
||||||
|
"sha256": "1a233f47943e01bbd845ac1dacdb1eec3f88c270c65a5f75bce1cf679b5de097"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "test_python_entry.py",
|
||||||
|
"bytes": 1760,
|
||||||
|
"sha256": "0ed665f686e3499f8543e48f1712ccb4523946971cb7a0e096cf4f6d10d3bcba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "validate_components.py",
|
||||||
|
"bytes": 24824,
|
||||||
|
"sha256": "5cfc9a4505da6b8fb4e7d2617cdaedaa8475ed46a11ec9bdf0d4d25b1d22c2d3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "verify_frozen.py",
|
||||||
|
"bytes": 2160,
|
||||||
|
"sha256": "0d0e72b2f1348f6648124c8c34f75094f76fc5e1a281fbcca130a5fad2f35293"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,747 @@
|
|||||||
|
"""Phase 4AG shared-APL-component closed-loop Brian oracle.
|
||||||
|
|
||||||
|
Brian has no Torch dependency. A separate, pinned science-Python process
|
||||||
|
executes the unchanged legacy float32 APL operations from Brian's own spikes.
|
||||||
|
This is independent LIF/scheduling validation with a shared APL numerical
|
||||||
|
component, NOT an all-components-independent CPU oracle.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import csv
|
||||||
|
import hashlib
|
||||||
|
import importlib.metadata
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import queue
|
||||||
|
import struct
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import types
|
||||||
|
from contextlib import ExitStack
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
BLOCK_BYTES = 8 << 20
|
||||||
|
PROTOCOL = "phase4ag-apl-v1"
|
||||||
|
AUTHOR_PATH = Path("/data/digital-drosophila/experiments/phase4ad-author-semantics/external-resources/model.py")
|
||||||
|
AUTHOR_SHA256 = "fc45837d7122c6ce2a7f3f2f23c515992e4b232aadb919efabb72337fac88e4e"
|
||||||
|
AE_PATH = Path("/data/digital-drosophila/models/male-cns-lif/author-runtime-lab-v1/oracle_stress.py")
|
||||||
|
AE_SHA256 = "32eb1c42383068ce52701d2139a376ce155ad7072cde019949f8ca2d55492409"
|
||||||
|
AF_PATH = Path("/data/digital-drosophila/models/male-cns-lif/author-fullgraph-lab-v1/oracle_full.py")
|
||||||
|
AF_SHA256 = "d72003d98f0f1624b12126eff50bd361c43d888f4a64d90ba9247a58976f1961"
|
||||||
|
EVENT_DTYPE = np.dtype([("step", "<i4"), ("neuron_idx", "<i4")])
|
||||||
|
BUNDLE_FILES = ("input_matrix.npy", "output_matrix.npy", "kc_globals.npy", "apl_globals.npy")
|
||||||
|
_PROCESS_USED = False
|
||||||
|
|
||||||
|
|
||||||
|
def _check(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def _save(path, value):
|
||||||
|
with Path(path).open("x", encoding="utf-8") as handle:
|
||||||
|
json.dump(value, handle, indent=2, sort_keys=True, allow_nan=False)
|
||||||
|
handle.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def _digest(path):
|
||||||
|
result = hashlib.sha256()
|
||||||
|
with Path(path).open("rb") as handle:
|
||||||
|
for block in iter(lambda: handle.read(BLOCK_BYTES), b""):
|
||||||
|
result.update(block)
|
||||||
|
return result.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _array_hash(array, dtype):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(array, dtype=dtype).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def _load_checked(path, expected, name):
|
||||||
|
data = Path(path).read_bytes()
|
||||||
|
_check(hashlib.sha256(data).hexdigest() == expected, f"Pinned source hash mismatch: {path}")
|
||||||
|
module = types.ModuleType(name)
|
||||||
|
module.__file__ = str(path)
|
||||||
|
exec(compile(data, str(path), "exec"), module.__dict__)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
def _python_entry(path):
|
||||||
|
"""A venv is selected by its invocation path, not the resolved ELF target."""
|
||||||
|
entry = Path(path).absolute()
|
||||||
|
_check(entry.is_file(), f"Missing declared Python entry: {entry}")
|
||||||
|
return entry
|
||||||
|
|
||||||
|
|
||||||
|
def _new_memmap(path, dtype, shape):
|
||||||
|
_check(not Path(path).exists(), f"Refusing to overwrite output: {path}")
|
||||||
|
return np.lib.format.open_memmap(path, mode="w+", dtype=dtype, shape=shape)
|
||||||
|
|
||||||
|
|
||||||
|
def _budget(root, limit, reserve=0):
|
||||||
|
total = 0
|
||||||
|
for directory, _, filenames in os.walk(root, followlinks=False):
|
||||||
|
for filename in filenames:
|
||||||
|
total += (Path(directory) / filename).stat(follow_symlinks=False).st_size
|
||||||
|
_check(total + int(reserve) <= limit,
|
||||||
|
f"Output budget exceeded: {total}+{reserve}>{limit}; inputs and duration were not adjusted")
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
class _PipeReader:
|
||||||
|
"""One bounded reader thread, with timeout/EOF checks for every frame."""
|
||||||
|
|
||||||
|
def __init__(self, pipe, timeout):
|
||||||
|
self.pipe, self.timeout = pipe, float(timeout)
|
||||||
|
self.chunks = queue.Queue(maxsize=8)
|
||||||
|
self.buffer = bytearray()
|
||||||
|
self.thread = threading.Thread(target=self._pump, daemon=True)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def _pump(self):
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
chunk = os.read(self.pipe.fileno(), 65536)
|
||||||
|
self.chunks.put(chunk)
|
||||||
|
if not chunk:
|
||||||
|
return
|
||||||
|
except BaseException as error:
|
||||||
|
self.chunks.put(error)
|
||||||
|
|
||||||
|
def _fill(self, deadline):
|
||||||
|
remaining = deadline - time.monotonic()
|
||||||
|
if remaining <= 0:
|
||||||
|
raise TimeoutError("APL sidecar response timed out")
|
||||||
|
try:
|
||||||
|
chunk = self.chunks.get(timeout=remaining)
|
||||||
|
except queue.Empty as error:
|
||||||
|
raise TimeoutError("APL sidecar response timed out") from error
|
||||||
|
if isinstance(chunk, BaseException):
|
||||||
|
raise RuntimeError("APL sidecar stdout reader failed") from chunk
|
||||||
|
if not chunk:
|
||||||
|
raise EOFError("APL sidecar ended before a complete response")
|
||||||
|
self.buffer.extend(chunk)
|
||||||
|
|
||||||
|
def read(self, size):
|
||||||
|
deadline = time.monotonic() + self.timeout
|
||||||
|
while len(self.buffer) < size:
|
||||||
|
self._fill(deadline)
|
||||||
|
result = bytes(self.buffer[:size])
|
||||||
|
del self.buffer[:size]
|
||||||
|
return result
|
||||||
|
|
||||||
|
def line(self):
|
||||||
|
deadline = time.monotonic() + self.timeout
|
||||||
|
while b"\n" not in self.buffer:
|
||||||
|
_check(len(self.buffer) < 1 << 20, "APL sidecar handshake exceeds 1 MiB")
|
||||||
|
self._fill(deadline)
|
||||||
|
end = self.buffer.index(b"\n") + 1
|
||||||
|
result = bytes(self.buffer[:end])
|
||||||
|
del self.buffer[:end]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class _APLWorker:
|
||||||
|
def __init__(self, python, script, bundle_dir, stderr, timeout=180):
|
||||||
|
self.command = [str(python), "-B", str(script), "--bundle-dir", str(bundle_dir), "--dt-ms", "0.1"]
|
||||||
|
self.process = subprocess.Popen(self.command, stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE, stderr=stderr, bufsize=0, shell=False)
|
||||||
|
self.reader = _PipeReader(self.process.stdout, timeout)
|
||||||
|
self.tick = 0
|
||||||
|
try:
|
||||||
|
self.hello = json.loads(self.reader.line().decode("utf-8"))
|
||||||
|
_check(self.hello.get("ok") is True, "APL sidecar did not acknowledge initialization")
|
||||||
|
_check(self.hello.get("protocol") == PROTOCOL, "Unexpected APL sidecar protocol")
|
||||||
|
for key, value in (("n_neurons", 166700), ("n_apl", 2), ("n_kc", 4064)):
|
||||||
|
_check(self.hello.get(key) == value, f"APL sidecar changed {key}")
|
||||||
|
_check(self.hello.get("dt_ms") == .1, "APL sidecar changed dt")
|
||||||
|
expected_decay = f"{int(np.float32(math.exp(-.1 / 20.)).view(np.uint32)):08x}"
|
||||||
|
expected_gain = f"{int(np.float32(.01).view(np.uint32)):08x}"
|
||||||
|
_check(self.hello.get("decay_f32_bits") == expected_decay and self.hello.get("gain_f32_bits") == expected_gain,
|
||||||
|
"APL sidecar decay/gain differs from the frozen float32 scalars")
|
||||||
|
_check(self.hello.get("files_sha256") == {name: _digest(bundle_dir / name) for name in BUNDLE_FILES},
|
||||||
|
"APL sidecar bundle hashes differ from the independently read bundle")
|
||||||
|
except BaseException:
|
||||||
|
self.abort()
|
||||||
|
raise
|
||||||
|
|
||||||
|
def step(self, tick, global_spikes):
|
||||||
|
_check(tick == self.tick, "APL sidecar request ticks must be consecutive")
|
||||||
|
nodes = np.asarray(global_spikes)
|
||||||
|
_check(nodes.ndim == 1 and nodes.dtype == np.dtype("int32"), "APL input spikes must be int32 globals")
|
||||||
|
_check(not len(nodes) or (nodes[0] >= 0 and nodes[-1] < 166700 and np.all(np.diff(nodes) > 0)),
|
||||||
|
"APL input spikes must be sorted, unique, and in the frozen global range")
|
||||||
|
packet = struct.pack("<qQ", int(tick), len(nodes)) + np.ascontiguousarray(nodes, dtype="<i4").tobytes()
|
||||||
|
view = memoryview(packet)
|
||||||
|
while view:
|
||||||
|
written = self.process.stdin.write(view)
|
||||||
|
if not written:
|
||||||
|
raise BrokenPipeError("APL sidecar stdin failed")
|
||||||
|
view = view[written:]
|
||||||
|
self.process.stdin.flush()
|
||||||
|
response_tick, byte_count = struct.unpack("<qQ", self.reader.read(16))
|
||||||
|
_check(response_tick == tick and byte_count == (2 + 2 + 4064) * 4,
|
||||||
|
"APL sidecar frame tick/length mismatch")
|
||||||
|
values = np.frombuffer(self.reader.read(byte_count), dtype="<f4")
|
||||||
|
_check(np.isfinite(values).all() and np.all(values >= 0), "APL sidecar returned invalid nonnegative f32 states")
|
||||||
|
self.tick += 1
|
||||||
|
return values[:2], values[2:4], values[4:]
|
||||||
|
|
||||||
|
def finish(self, steps):
|
||||||
|
_check(self.tick == steps, "APL sidecar did not process every tick")
|
||||||
|
self.process.stdin.close()
|
||||||
|
status = self.process.wait(timeout=30)
|
||||||
|
_check(status == 0, f"APL sidecar exited unsuccessfully: {status}")
|
||||||
|
self.reader.thread.join(timeout=5)
|
||||||
|
_check(not self.reader.thread.is_alive(), "APL stdout did not reach EOF")
|
||||||
|
extra = bytes(self.reader.buffer)
|
||||||
|
while not self.reader.chunks.empty():
|
||||||
|
chunk = self.reader.chunks.get_nowait()
|
||||||
|
_check(not isinstance(chunk, BaseException), "APL stdout reader failed after the last frame")
|
||||||
|
extra += chunk
|
||||||
|
_check(not extra, "APL sidecar emitted unrequested trailing stdout bytes")
|
||||||
|
self.process.stdout.close()
|
||||||
|
return status
|
||||||
|
|
||||||
|
def abort(self):
|
||||||
|
if self.process.poll() is None:
|
||||||
|
self.process.terminate()
|
||||||
|
try:
|
||||||
|
self.process.wait(timeout=5)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
self.process.kill()
|
||||||
|
self.process.wait(timeout=5)
|
||||||
|
for handle in (self.process.stdin, self.process.stdout):
|
||||||
|
if handle is not None and not handle.closed:
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
|
||||||
|
def _graph_inputs(directory):
|
||||||
|
arrays = {}
|
||||||
|
definitions = {"nodes": "int32", "edge_id": "int64", "src": "int32",
|
||||||
|
"dst": "int32", "signed_raw": "int64", "ptr": "int64", "weights": "float64"}
|
||||||
|
for name, dtype in definitions.items():
|
||||||
|
value = np.load(directory / (name + ".npy"), mmap_mode="r", allow_pickle=False)
|
||||||
|
_check(value.ndim == 1 and value.dtype == np.dtype(dtype), f"Invalid graph array {name}")
|
||||||
|
arrays[name] = value
|
||||||
|
nodes, edge_ids = arrays["nodes"], arrays["edge_id"]
|
||||||
|
n, edges = len(nodes), len(edge_ids)
|
||||||
|
_check(0 < n <= 166700 and edges > 0, "A case needs real global nodes and explicit nonempty connectivity")
|
||||||
|
_check(nodes[0] >= 0 and nodes[-1] < 166700 and np.all(np.diff(nodes) > 0), "Invalid global node order")
|
||||||
|
for name in ("src", "dst", "signed_raw", "weights"):
|
||||||
|
_check(arrays[name].shape == (edges,), f"Graph array {name} has the wrong shape")
|
||||||
|
pointer = arrays["ptr"]
|
||||||
|
_check(pointer.shape == (n + 1,) and pointer[0] == 0 and pointer[-1] == edges and
|
||||||
|
np.all(np.diff(pointer) >= 0), "Invalid graph CSR pointer")
|
||||||
|
source_counts = np.zeros(n, np.int64)
|
||||||
|
identity_edges = True
|
||||||
|
previous_source, previous_edge = -1, -1
|
||||||
|
width = BLOCK_BYTES // 8
|
||||||
|
for begin in range(0, edges, width):
|
||||||
|
stop = min(edges, begin + width)
|
||||||
|
source, target, ids = arrays["src"][begin:stop], arrays["dst"][begin:stop], edge_ids[begin:stop]
|
||||||
|
_check(np.all((source >= 0) & (source < n)) and np.all((target >= 0) & (target < n)),
|
||||||
|
"Graph edge endpoint is outside the local node array")
|
||||||
|
_check(np.all(ids >= 0), "Graph edge IDs must be nonnegative")
|
||||||
|
_check(source[0] > previous_source or (source[0] == previous_source and ids[0] > previous_edge),
|
||||||
|
"Graph edge blocks are not in canonical source/edge order")
|
||||||
|
_check(np.all((source[1:] > source[:-1]) |
|
||||||
|
((source[1:] == source[:-1]) & (ids[1:] > ids[:-1]))),
|
||||||
|
"Graph edges are not in canonical source/edge order")
|
||||||
|
previous_source, previous_edge = int(source[-1]), int(ids[-1])
|
||||||
|
identity_edges &= np.array_equal(ids, np.arange(begin, stop, dtype=np.int64))
|
||||||
|
source_counts += np.bincount(source, minlength=n)
|
||||||
|
_check(np.isfinite(arrays["weights"][begin:stop]).all(), "Nonfinite graph weights")
|
||||||
|
_check(np.array_equal(source_counts, np.diff(pointer)), "CSR pointer and source rows disagree")
|
||||||
|
if not identity_edges:
|
||||||
|
_check(len(np.unique(edge_ids)) == edges, "Original edge IDs must be unique")
|
||||||
|
for name in ("completeness.csv", "connectivity.parquet"):
|
||||||
|
_check((directory / name).is_file(), f"Missing unchanged author input: {name}")
|
||||||
|
if n == 166700:
|
||||||
|
_check(edges == 25582938 and identity_edges and np.array_equal(nodes, np.arange(n, dtype=np.int32)),
|
||||||
|
"A full probe must use the unchanged complete canonical graph")
|
||||||
|
return arrays, identity_edges
|
||||||
|
|
||||||
|
|
||||||
|
def _requests(case_dir, nodes, steps):
|
||||||
|
with np.load(case_dir / "requests.npz", allow_pickle=False) as archive:
|
||||||
|
_check(set(archive.files) == {"tick", "neuron_idx"}, "Unexpected sparse request schema")
|
||||||
|
ticks, requested = archive["tick"].copy(), archive["neuron_idx"].copy()
|
||||||
|
_check(ticks.dtype == requested.dtype == np.dtype("int32") and ticks.ndim == requested.ndim == 1 and
|
||||||
|
ticks.shape == requested.shape, "Requests must be equal-length int32 vectors")
|
||||||
|
_check(np.all((ticks >= 0) & (ticks < steps)), "Request time outside the case")
|
||||||
|
_check(not len(ticks) or np.all((ticks[1:] > ticks[:-1]) |
|
||||||
|
((ticks[1:] == ticks[:-1]) & (requested[1:] > requested[:-1]))),
|
||||||
|
"Requests must be sorted and unique by tick/global node")
|
||||||
|
local = np.searchsorted(nodes, requested)
|
||||||
|
_check(np.all(local < len(nodes)) and np.array_equal(nodes[local], requested),
|
||||||
|
"Request references a global neuron absent from this case")
|
||||||
|
counts = np.bincount(ticks, minlength=steps).astype(np.int32)
|
||||||
|
pointer = np.concatenate((np.zeros(1, np.int64), np.cumsum(counts, dtype=np.int64)))
|
||||||
|
return requested, local.astype(np.int32), pointer, counts
|
||||||
|
|
||||||
|
|
||||||
|
class _QueueProxy:
|
||||||
|
def __init__(self, original, get_tick, available, arrays, identity_edges,
|
||||||
|
due_counts, spike_ring, delay_steps, handle, records, summarize):
|
||||||
|
self._original_queue, self._get_tick = original, get_tick
|
||||||
|
self._available, self._arrays, self._identity_edges = available, arrays, identity_edges
|
||||||
|
self._due_counts, self._spike_ring, self._delay_steps = due_counts, spike_ring, delay_steps
|
||||||
|
self._handle, self._records, self._summarize = handle, records, summarize
|
||||||
|
|
||||||
|
def peek(self, *args, **kwargs):
|
||||||
|
original = self._original_queue.peek(*args, **kwargs)
|
||||||
|
local_edges = np.asarray(original)
|
||||||
|
tick = self._get_tick()
|
||||||
|
_check(tick == len(self._records["rows"]), "Queue peek ticks must be consecutive")
|
||||||
|
_check(local_edges.ndim == 1 and np.all((local_edges >= 0) & (local_edges < len(self._arrays["edge_id"]))),
|
||||||
|
"Original queue contains an invalid local edge index")
|
||||||
|
_check(len(local_edges) == self._due_counts[tick % len(self._due_counts)],
|
||||||
|
"Queue arrivals differ from the fixed-delay outgoing degree of actual spikes")
|
||||||
|
fired_then = np.zeros(len(self._arrays["nodes"]), dtype=bool)
|
||||||
|
if tick >= self._delay_steps:
|
||||||
|
fired_then[self._spike_ring[(tick - self._delay_steps) % len(self._spike_ring)]] = True
|
||||||
|
|
||||||
|
def accepted(begin, stop):
|
||||||
|
part = local_edges[begin:stop]
|
||||||
|
_check(np.all(fired_then[self._arrays["src"][part]]), "Arrival lacks a presynaptic spike at author delay")
|
||||||
|
return self._available[self._arrays["dst"][part]]
|
||||||
|
|
||||||
|
# Only the observed ID view changes; the queue is returned verbatim.
|
||||||
|
edge_ids = local_edges if self._identity_edges else self._arrays["edge_id"][local_edges]
|
||||||
|
summary = self._summarize(tick, edge_ids, accepted)
|
||||||
|
self._handle.write(json.dumps(summary, sort_keys=True) + "\n")
|
||||||
|
self._records["rows"].append(summary)
|
||||||
|
self._records["peek_calls"] += 1
|
||||||
|
return original
|
||||||
|
|
||||||
|
def advance(self, *args, **kwargs):
|
||||||
|
self._records["advance_calls"] += 1
|
||||||
|
return self._original_queue.advance(*args, **kwargs)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(self._original_queue, name)
|
||||||
|
|
||||||
|
|
||||||
|
def run_case(case_dir: Path, out_dir: Path) -> dict:
|
||||||
|
"""Run one continuous case, with exclusive outputs and no candidate trace input.
|
||||||
|
|
||||||
|
Graph inputs are the AF array/author-table schema plus original weights.npy.
|
||||||
|
requests.npz contains sparse tick/neuron_idx int32 vectors. Optional
|
||||||
|
arrays.npz contains initial_v_mv/initial_g_mv float64 vectors only.
|
||||||
|
Full probes write state hashes, sparse events and APL traces, not dense
|
||||||
|
whole-brain histories. Each case requires a fresh process.
|
||||||
|
"""
|
||||||
|
global _PROCESS_USED
|
||||||
|
_check(not _PROCESS_USED, "Every oracle case requires a fresh process")
|
||||||
|
_PROCESS_USED = True
|
||||||
|
case_dir, out_dir = Path(case_dir).resolve(strict=True), Path(out_dir).resolve()
|
||||||
|
spec = json.loads((case_dir / "spec.json").read_text(encoding="utf-8"))
|
||||||
|
graph_dir = Path(spec["graph_dir"]).resolve(strict=True)
|
||||||
|
bundle_dir = Path(spec["apl_bundle_dir"]).resolve(strict=True)
|
||||||
|
worker_path = Path(spec["legacy_apl_worker"]).resolve(strict=True)
|
||||||
|
science_python = _python_entry(spec["science_python"])
|
||||||
|
author_path = Path(spec.get("author_path", AUTHOR_PATH)).resolve(strict=True)
|
||||||
|
ae_path = Path(spec.get("ae_oracle_path", AE_PATH)).resolve(strict=True)
|
||||||
|
af_path = Path(spec.get("af_oracle_path", AF_PATH)).resolve(strict=True)
|
||||||
|
coefficients_path = Path(spec["coefficients_path"]).resolve(strict=True)
|
||||||
|
steps = int(spec["steps"])
|
||||||
|
_check(steps == spec["steps"] and 0 < steps <= np.iinfo(np.int32).max, "Invalid number of steps")
|
||||||
|
_check(float(spec["dt_ms"]) == .1 and np.isclose(float(spec["duration_ms"]), steps * .1, rtol=0, atol=1e-12),
|
||||||
|
"The frozen APL protocol requires dt_ms=0.1 and a matching duration")
|
||||||
|
_check(spec.get("precision", "float64") == "float64", "Author state must be float64")
|
||||||
|
_check(spec.get("training", False) is False and spec.get("poi_used", False) is False,
|
||||||
|
"Training and original poi are outside this gate")
|
||||||
|
_check(spec["apl"] == {"tau_ms": 20, "gain": .01, "normalization": 1}, "Frozen APL parameters changed")
|
||||||
|
record_history = spec["record_history"]
|
||||||
|
_check(isinstance(record_history, bool), "record_history must be a boolean")
|
||||||
|
budget_root = Path(spec.get("budget_root", out_dir.parent)).resolve()
|
||||||
|
budget_limit = int(spec.get("output_budget_bytes", 15 * 1024 ** 3))
|
||||||
|
_check(budget_limit > 0 and out_dir.is_relative_to(budget_root), "Invalid output budget/root")
|
||||||
|
out_dir.mkdir(parents=True, exist_ok=False)
|
||||||
|
mapped_files = []
|
||||||
|
saved_preferences, old_dt, worker = None, None, None
|
||||||
|
last_complete_tick = -1
|
||||||
|
try:
|
||||||
|
arrays, identity_edges = _graph_inputs(graph_dir)
|
||||||
|
nodes, n, edges = arrays["nodes"], len(arrays["nodes"]), len(arrays["edge_id"])
|
||||||
|
_check(n < 166700 or not record_history, "Full probes must not save dense V/g/ref histories")
|
||||||
|
bundle = {name: np.load(bundle_dir / (name + ".npy"), mmap_mode="r", allow_pickle=False)
|
||||||
|
for name in ("input_matrix", "output_matrix", "kc_globals", "apl_globals")}
|
||||||
|
for name, shape in (("input_matrix", (2, 166700)), ("output_matrix", (2, 4064))):
|
||||||
|
value = bundle[name]
|
||||||
|
_check(value.dtype == np.dtype("float32") and value.shape == shape and value.flags.c_contiguous,
|
||||||
|
f"Frozen APL {name} shape/dtype/layout changed")
|
||||||
|
_check(np.isfinite(value).all() and np.all(value >= 0), f"Invalid positive raw-normalized APL {name}")
|
||||||
|
for name, count in (("kc_globals", 4064), ("apl_globals", 2)):
|
||||||
|
value = bundle[name]
|
||||||
|
_check(value.dtype == np.dtype("int32") and value.shape == (count,) and value[0] >= 0 and
|
||||||
|
value[-1] < 166700 and np.all(np.diff(value) > 0), f"Frozen APL identity {name} changed")
|
||||||
|
_check(not np.intersect1d(bundle["kc_globals"], bundle["apl_globals"]).size, "APL and KC identities overlap")
|
||||||
|
kc_positions = np.searchsorted(nodes, bundle["kc_globals"])
|
||||||
|
present = kc_positions < n
|
||||||
|
present[present] &= nodes[kc_positions[present]] == bundle["kc_globals"][present]
|
||||||
|
kc_local, kc_in_bundle = kc_positions[present], np.flatnonzero(present)
|
||||||
|
requested_globals, request_local, request_ptr, request_count = _requests(case_dir, nodes, steps)
|
||||||
|
initial = None
|
||||||
|
if (case_dir / "arrays.npz").exists():
|
||||||
|
with np.load(case_dir / "arrays.npz", allow_pickle=False) as archive:
|
||||||
|
_check(set(archive.files) == {"initial_v_mv", "initial_g_mv"}, "Unexpected initial-state schema")
|
||||||
|
initial = {name: archive[name].copy() for name in archive.files}
|
||||||
|
for name, value in initial.items():
|
||||||
|
_check(value.dtype == np.dtype("float64") and value.shape == (n,) and np.isfinite(value).all(),
|
||||||
|
f"Invalid diagnostic initial state: {name}")
|
||||||
|
history_bytes = steps * n * 40 if record_history else 0
|
||||||
|
_budget(budget_root, budget_limit, history_bytes + steps * (2 + 2 + 4064) * 4 + edges * 8 + (64 << 20))
|
||||||
|
versions = {name: importlib.metadata.version(name) for name in
|
||||||
|
("brian2", "numpy", "pandas", "pyarrow", "sympy", "scipy", "cython")}
|
||||||
|
_save(out_dir / "environment.json", {"python": sys.version, "platform": platform.platform(),
|
||||||
|
"packages": versions, "codegen": "numpy", "author_precision": "float64",
|
||||||
|
"APL_precision": "float32 in separate science-Python process", "Torch_imported_into_Brian": False})
|
||||||
|
for name, required in (("brian2", "2.5.1"), ("numpy", "1.22.3"), ("sympy", "1.12")):
|
||||||
|
_check(versions[name] == required, f"{name} must remain pinned to {required}")
|
||||||
|
import brian2 as b2
|
||||||
|
import pandas as pd
|
||||||
|
from brian2.core.base import BrianObject
|
||||||
|
|
||||||
|
ae = _load_checked(ae_path, AE_SHA256, "phase4ag_sealed_ae_helpers")
|
||||||
|
af = _load_checked(af_path, AF_SHA256, "phase4ag_sealed_af_helpers")
|
||||||
|
author = _load_checked(author_path, AUTHOR_SHA256, "phase4ag_unchanged_author")
|
||||||
|
_check("torch" not in sys.modules, "Torch must not be imported into the pinned Brian process")
|
||||||
|
comp = pd.read_csv(graph_dir / "completeness.csv", index_col=0)
|
||||||
|
_check(np.array_equal(comp.index.to_numpy(), nodes) and
|
||||||
|
np.array_equal(comp["local_index"].to_numpy(), np.arange(n)), "Author CSV neuron identity differs")
|
||||||
|
del comp
|
||||||
|
graph_hashes = {name: _digest(graph_dir / name) for name in
|
||||||
|
tuple(key + ".npy" for key in arrays) + ("completeness.csv", "connectivity.parquet")}
|
||||||
|
bundle_hashes = {name: _digest(bundle_dir / name) for name in BUNDLE_FILES}
|
||||||
|
case_hashes = {name: _digest(case_dir / name) for name in ("spec.json", "requests.npz")}
|
||||||
|
if initial is not None:
|
||||||
|
case_hashes["arrays.npz"] = _digest(case_dir / "arrays.npz")
|
||||||
|
worker_hash = _digest(worker_path)
|
||||||
|
coefficient_hash = _digest(coefficients_path)
|
||||||
|
baseline_coefficients = json.loads(coefficients_path.read_text(encoding="utf-8"))
|
||||||
|
if "legacy_apl_worker_sha256" in spec:
|
||||||
|
_check(worker_hash == spec["legacy_apl_worker_sha256"], "APL worker differs from preregistered source")
|
||||||
|
_save(out_dir / "input-audit.json", {"spec": spec, "case_hashes": case_hashes,
|
||||||
|
"graph_hashes": graph_hashes, "bundle_hashes": bundle_hashes,
|
||||||
|
"author_sha256": AUTHOR_SHA256, "ae_sha256": AE_SHA256, "af_sha256": AF_SHA256,
|
||||||
|
"legacy_apl_worker_sha256": worker_hash, "coefficients_sha256": coefficient_hash,
|
||||||
|
"candidate_trace_used_as_input": False,
|
||||||
|
"scope": "shared-APL-component closed-loop oracle, not all-components-independent CPU equivalence"})
|
||||||
|
saved_preferences = {key: b2.prefs[key] for key in
|
||||||
|
("codegen.target", "core.default_float_dtype", "legacy.refractory_timing")}
|
||||||
|
old_dt = b2.defaultclock.dt
|
||||||
|
b2.start_scope()
|
||||||
|
b2.prefs["codegen.target"] = "numpy"
|
||||||
|
b2.prefs["core.default_float_dtype"] = np.float64
|
||||||
|
b2.prefs["legacy.refractory_timing"] = False
|
||||||
|
b2.defaultclock.dt = .1 * b2.ms
|
||||||
|
parameters = dict(author.default_params)
|
||||||
|
_save(out_dir / "parameter-checks.json", ae._parameters_match(parameters, spec["model"], b2))
|
||||||
|
neu, syn, spikes = author.create_model(graph_dir / "completeness.csv", graph_dir / "connectivity.parquet", parameters)
|
||||||
|
_check(len(neu) == n and len(syn) == edges, "Author loaded an unexpected graph size")
|
||||||
|
_check(all(np.dtype(neu.variables[key].dtype) == np.float64 for key in ("v", "g")) and
|
||||||
|
np.dtype(syn.variables["w"].dtype) == np.float64, "Author states/weights are not float64")
|
||||||
|
effective = _new_memmap(out_dir / "weights.npy", "<f8", (edges,))
|
||||||
|
mapped_files.append(effective)
|
||||||
|
width, w_unit, mask_count = BLOCK_BYTES // 8, float(parameters["w_syn"] / b2.volt), 0
|
||||||
|
mask_hasher = hashlib.sha256()
|
||||||
|
base_hasher = hashlib.sha256()
|
||||||
|
effective_hasher = hashlib.sha256()
|
||||||
|
for begin in range(0, edges, width):
|
||||||
|
stop = min(edges, begin + width)
|
||||||
|
np.testing.assert_array_equal(np.asarray(syn.i[begin:stop]), arrays["src"][begin:stop])
|
||||||
|
np.testing.assert_array_equal(np.asarray(syn.j[begin:stop]), arrays["dst"][begin:stop])
|
||||||
|
original = np.asarray(syn.w_[begin:stop], dtype=np.float64).copy()
|
||||||
|
raw_expected = arrays["signed_raw"][begin:stop] * w_unit
|
||||||
|
_check(np.array_equal(original.view(np.uint64), raw_expected.view(np.uint64)) and
|
||||||
|
np.array_equal(original.view(np.uint64), arrays["weights"][begin:stop].view(np.uint64)),
|
||||||
|
"Actual original Brian weights differ from unchanged signed raw or AF base weights")
|
||||||
|
base_hasher.update(np.ascontiguousarray(original, dtype="<f8").tobytes())
|
||||||
|
mask = np.isin(nodes[arrays["src"][begin:stop]], bundle["apl_globals"])
|
||||||
|
mask_count += int(mask.sum())
|
||||||
|
mask_hasher.update(np.ascontiguousarray(arrays["edge_id"][begin:stop][mask], dtype="<i8").tobytes())
|
||||||
|
original[mask] = np.float64(0.0)
|
||||||
|
effective_hasher.update(np.ascontiguousarray(original, dtype="<f8").tobytes())
|
||||||
|
effective[begin:stop] = original
|
||||||
|
syn.w_[begin:stop] = original
|
||||||
|
if n == 166700:
|
||||||
|
_check(mask_count == 5845, "Full legacy APL fast-edge mask must contain exactly 5845 existing edges")
|
||||||
|
effective.flush()
|
||||||
|
_save(out_dir / "apl-mask-audit.json", {"count": mask_count, "ordered_original_edge_id_sha256": mask_hasher.hexdigest(),
|
||||||
|
"base_weight_raw_bytes_sha256": base_hasher.hexdigest(), "effective_weights_file_sha256": _digest(out_dir / "weights.npy"),
|
||||||
|
"effective_weights_raw_sha256": effective_hasher.hexdigest(),
|
||||||
|
"rule": "zero +0 all existing fast edges whose source GLOBAL neuron is in apl_globals; no graph edge removal",
|
||||||
|
"graded_targets": "only KC identities present in this LIF case", "KC_targets_in_case": len(kc_local),
|
||||||
|
"base_graph_files_modified": False, "fullgraph_required_mask_count": 5845})
|
||||||
|
if initial is not None:
|
||||||
|
neu.v = initial["initial_v_mv"] * b2.mV
|
||||||
|
neu.g = initial["initial_g_mv"] * b2.mV
|
||||||
|
v_raw = neu.variables["v"].get_value()
|
||||||
|
g_raw = neu.variables["g"].get_value()
|
||||||
|
last_raw = neu.variables["lastspike"].get_value()
|
||||||
|
available_raw = neu.variables["not_refractory"].get_value()
|
||||||
|
histories = {}
|
||||||
|
pre_apl_histories = {}
|
||||||
|
if record_history:
|
||||||
|
for name, dtype in (("v", "float64"), ("g", "float64"), ("ref", "int32")):
|
||||||
|
histories[name] = _new_memmap(out_dir / f"{name}-history.{dtype}.npy", np.dtype(dtype), (steps, n))
|
||||||
|
mapped_files.append(histories[name])
|
||||||
|
pre_apl_histories[name] = _new_memmap(out_dir / f"preAPL-{name}.{dtype}.npy", np.dtype(dtype), (steps, n))
|
||||||
|
mapped_files.append(pre_apl_histories[name])
|
||||||
|
apl_history = {}
|
||||||
|
for name, count in (("drive", 2), ("state", 2), ("inhibition", 4064)):
|
||||||
|
apl_history[name] = _new_memmap(out_dir / f"apl-{name}.float32.npy", "<f4", (steps, count))
|
||||||
|
mapped_files.append(apl_history[name])
|
||||||
|
_save(out_dir / "output-schema.json", {"history_recorded": record_history, "history_shape": [steps, n],
|
||||||
|
"state_hash_file": "tick-state-hashes.jsonl", "state_hash_encoding": "SHA256 of contiguous little-endian raw f64 V/g and i32 ref",
|
||||||
|
"APL_dtype": "float32", "APL_h_units": "mV; gain already applied in float32",
|
||||||
|
"APL_SI_conversion": "h.astype(float64) * float64(0.001), then separate float64 g subtraction",
|
||||||
|
"APL_write_schedule": "end, order=0, after original reset, unconditional raw g write; recorder end/order=1",
|
||||||
|
"APL_input": "Brian's own actual global spikes, never candidate spikes or candidate inhibition",
|
||||||
|
"APL_shapes": {"drive": [steps, 2], "state": [steps, 2], "inhibition": [steps, 4064]},
|
||||||
|
"request_columns": ["tick", "neuron_idx", "attempted", "accepted", "rejected"],
|
||||||
|
"queue_protocol": "sealed Phase4AF queue_summary; original global edge IDs, including zero-weight/ref-rejected arrivals",
|
||||||
|
"state_npz": ["step", "neuron_idx", "counts", "v", "g", "ref"],
|
||||||
|
"complete_marker": "summary.json complete=true only after worker exit and all checks"})
|
||||||
|
delay_steps = int(round(float(parameters["t_dly"] / b2.ms) / .1))
|
||||||
|
ref_steps = int(round(float(parameters["t_rfc"] / b2.ms) / .1))
|
||||||
|
_check(delay_steps == 18 and ref_steps == 22, "Author delay/refractory changed")
|
||||||
|
queue_len = delay_steps + 1
|
||||||
|
due_counts = np.zeros(queue_len, np.int64)
|
||||||
|
spike_ring = [np.empty(0, np.int32) for _ in range(queue_len)]
|
||||||
|
outdegree = np.diff(arrays["ptr"])
|
||||||
|
request_seen = np.zeros(steps, np.uint8)
|
||||||
|
apl_seen = np.zeros(steps, np.uint8)
|
||||||
|
applicable_count = np.zeros(steps, np.int32)
|
||||||
|
rejected_count = np.zeros(steps, np.int32)
|
||||||
|
spike_count = np.zeros(steps, np.int32)
|
||||||
|
total_counts = np.zeros(n, np.int32)
|
||||||
|
records = {"rows": [], "peek_calls": 0, "advance_calls": 0, "installations": []}
|
||||||
|
last_ticks = np.zeros(n, np.int64)
|
||||||
|
final_ref = np.zeros(n, np.int32)
|
||||||
|
permitted = np.empty(0, np.int32)
|
||||||
|
total_events = 0
|
||||||
|
|
||||||
|
def tick_now():
|
||||||
|
return int(round(float(neu.clock.t / b2.second) / .0001))
|
||||||
|
|
||||||
|
def current_ref(tick):
|
||||||
|
seen = np.isfinite(last_raw) & (last_raw >= 0)
|
||||||
|
last_ticks.fill(0)
|
||||||
|
last_ticks[seen] = np.rint(last_raw[seen] / .0001).astype(np.int64)
|
||||||
|
result = np.where(seen, np.maximum(ref_steps - (tick - last_ticks), 0), 0).astype(np.int32)
|
||||||
|
_check(np.array_equal(result == 0, available_raw), "Ref history disagrees with author not_refractory")
|
||||||
|
return result
|
||||||
|
|
||||||
|
with ExitStack() as stack:
|
||||||
|
stderr = stack.enter_context((out_dir / "apl-worker.stderr.log").open("xb"))
|
||||||
|
worker = _APLWorker(science_python, worker_path, bundle_dir, stderr, float(spec.get("worker_timeout_seconds", 180)))
|
||||||
|
_save(out_dir / "apl-worker-handshake.json", {"command": worker.command, "handshake": worker.hello})
|
||||||
|
queue_file = stack.enter_context((out_dir / "queue.jsonl").open("x", encoding="utf-8"))
|
||||||
|
event_file = stack.enter_context((out_dir / "events.bin").open("xb"))
|
||||||
|
hash_file = stack.enter_context((out_dir / "tick-state-hashes.jsonl").open("x", encoding="utf-8"))
|
||||||
|
tick_file = stack.enter_context((out_dir / "ticks.jsonl").open("x", encoding="utf-8"))
|
||||||
|
requests_file = stack.enter_context((out_dir / "requests.csv").open("x", encoding="utf-8", newline=""))
|
||||||
|
request_writer = csv.DictWriter(requests_file, fieldnames=["tick", "neuron_idx", "attempted", "accepted", "rejected"])
|
||||||
|
request_writer.writeheader()
|
||||||
|
|
||||||
|
def request_operation():
|
||||||
|
nonlocal permitted
|
||||||
|
tick = tick_now()
|
||||||
|
_check(0 <= tick < steps and not request_seen[tick], "Invalid/duplicate common request tick")
|
||||||
|
request_seen[tick] = 1
|
||||||
|
begin, stop = request_ptr[tick:tick + 2]
|
||||||
|
local = request_local[begin:stop]
|
||||||
|
available = available_raw[local].copy()
|
||||||
|
permitted = local[available]
|
||||||
|
applicable_count[tick] = len(permitted)
|
||||||
|
rejected_count[tick] = len(local) - len(permitted)
|
||||||
|
for node, accepted in zip(requested_globals[begin:stop], available):
|
||||||
|
request_writer.writerow({"tick": tick, "neuron_idx": int(node), "attempted": 1,
|
||||||
|
"accepted": int(accepted), "rejected": int(not accepted)})
|
||||||
|
if len(permitted):
|
||||||
|
neu.v[permitted] = parameters["v_th"] + 1 * b2.mV
|
||||||
|
|
||||||
|
def apl_operation():
|
||||||
|
tick = tick_now()
|
||||||
|
_check(0 <= tick < steps and not apl_seen[tick] and request_seen[tick], "Invalid/duplicate APL tick")
|
||||||
|
active = np.asarray(neu.spikes, dtype=np.int32)
|
||||||
|
_check(not len(active) or np.all(np.diff(active) > 0), "Brian actual spikes are not canonical/unique")
|
||||||
|
_check(np.all(g_raw[active] == 0.0), "APL ran before the original author g reset")
|
||||||
|
if record_history:
|
||||||
|
pre_apl_histories["v"][tick] = v_raw
|
||||||
|
pre_apl_histories["g"][tick] = g_raw
|
||||||
|
pre_apl_histories["ref"][tick] = current_ref(tick)
|
||||||
|
drive, state, inhibition = worker.step(tick, np.asarray(nodes[active], dtype=np.int32))
|
||||||
|
apl_history["drive"][tick] = drive
|
||||||
|
apl_history["state"][tick] = state
|
||||||
|
apl_history["inhibition"][tick] = inhibition
|
||||||
|
# These are separate array operations. Do not move the unit
|
||||||
|
# conversion into a fused subtract; do not guard by refractory.
|
||||||
|
delta_si = inhibition[kc_in_bundle].astype(np.float64) * np.float64(.001)
|
||||||
|
g_raw[kc_local] = g_raw[kc_local] - delta_si
|
||||||
|
apl_seen[tick] = 1
|
||||||
|
|
||||||
|
def record_end():
|
||||||
|
nonlocal last_complete_tick, total_events, final_ref
|
||||||
|
tick = tick_now()
|
||||||
|
_check(tick == last_complete_tick + 1 and tick < steps and apl_seen[tick], "End tick is incomplete/out of order")
|
||||||
|
_check(len(records["rows"]) == tick + 1, "End state lacks queue observation")
|
||||||
|
_check(np.isfinite(v_raw).all() and np.isfinite(g_raw).all(), "Nonfinite author/APL state")
|
||||||
|
final_ref = current_ref(tick)
|
||||||
|
if record_history:
|
||||||
|
histories["v"][tick], histories["g"][tick], histories["ref"][tick] = v_raw, g_raw, final_ref
|
||||||
|
active = np.asarray(neu.spikes, dtype=np.int32)
|
||||||
|
_check(np.isin(permitted, active).all(), "An applicable request did not produce a real spike")
|
||||||
|
spike_count[tick] = len(active)
|
||||||
|
total_counts[active] += 1
|
||||||
|
if len(active):
|
||||||
|
events = np.empty(len(active), EVENT_DTYPE)
|
||||||
|
events["step"], events["neuron_idx"] = tick, nodes[active]
|
||||||
|
event_file.write(memoryview(events).cast("B"))
|
||||||
|
total_events += len(active)
|
||||||
|
spike_ring[tick % queue_len] = active.copy()
|
||||||
|
due_counts[(tick + delay_steps) % queue_len] = int(outdegree[active].sum(dtype=np.int64))
|
||||||
|
hash_file.write(json.dumps({"tick": tick, "v_sha256": _array_hash(v_raw, "<f8"),
|
||||||
|
"g_sha256": _array_hash(g_raw, "<f8"), "ref_sha256": _array_hash(final_ref, "<i4")}, sort_keys=True) + "\n")
|
||||||
|
tick_file.write(json.dumps({"tick": tick, "spikes": len(active), "requests": int(request_count[tick]),
|
||||||
|
"applicable_requests": int(applicable_count[tick]), "ref_rejected_requests": int(rejected_count[tick]),
|
||||||
|
"event_sha256": _array_hash(nodes[active], "<i4"),
|
||||||
|
"due_arrivals": records["rows"][tick]["count"], "accepted_arrivals": records["rows"][tick]["accepted_count"],
|
||||||
|
"APL_drive_sha256": _array_hash(apl_history["drive"][tick], "<f4"),
|
||||||
|
"APL_state_sha256": _array_hash(apl_history["state"][tick], "<f4"),
|
||||||
|
"APL_inhibition_sha256": _array_hash(apl_history["inhibition"][tick], "<f4")}, sort_keys=True) + "\n")
|
||||||
|
_budget(budget_root, budget_limit, reserve=1 << 20)
|
||||||
|
last_complete_tick = tick
|
||||||
|
if (tick + 1) % 100 == 0 or tick + 1 == steps:
|
||||||
|
for mapped in mapped_files:
|
||||||
|
mapped.flush()
|
||||||
|
for handle in (queue_file, event_file, hash_file, tick_file, requests_file):
|
||||||
|
handle.flush()
|
||||||
|
print(json.dumps({"oracle": spec["name"], "completed_ticks": tick + 1,
|
||||||
|
"spikes": total_events, "APL_worker_ticks": worker.tick}), flush=True)
|
||||||
|
|
||||||
|
class QueueInstaller(BrianObject):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(clock=neu.clock, when="end", order=1_000_000, name="zz_apl_queue_installer")
|
||||||
|
|
||||||
|
def before_run(self, run_namespace):
|
||||||
|
installed = []
|
||||||
|
for code in syn.pre.code_objects:
|
||||||
|
if "_queue" not in code.namespace or "_queue.peek()" not in str(code.code):
|
||||||
|
continue
|
||||||
|
original = code.namespace["_queue"]
|
||||||
|
if isinstance(original, _QueueProxy):
|
||||||
|
original = original._original_queue
|
||||||
|
code.namespace["_queue"] = _QueueProxy(original, tick_now, available_raw, arrays, identity_edges,
|
||||||
|
due_counts, spike_ring, delay_steps, queue_file, records, af.queue_summary)
|
||||||
|
installed.append(code.name)
|
||||||
|
_check(len(installed) == 1, "Expected one original anatomical queue consumer")
|
||||||
|
records["installations"].append(installed[0])
|
||||||
|
|
||||||
|
objects = [neu, syn, spikes,
|
||||||
|
b2.NetworkOperation(request_operation, clock=neu.clock, when="before_thresholds", order=0, name="oracle_common_requests"),
|
||||||
|
b2.NetworkOperation(apl_operation, clock=neu.clock, when="end", order=0, name="oracle_legacy_apl_unconditional"),
|
||||||
|
b2.NetworkOperation(record_end, clock=neu.clock, when="end", order=1, name="oracle_after_apl_record"), QueueInstaller()]
|
||||||
|
network = b2.Network(*objects)
|
||||||
|
_save(out_dir / "schedule.json", {"schedule": list(network.schedule), "summary": str(network.scheduling_summary())})
|
||||||
|
network.run(0 * b2.ms, namespace={})
|
||||||
|
_save(out_dir / "compiled-code.json", ae._code_records(network))
|
||||||
|
compiled_coefficients = ae._coefficients(neu, parameters, b2, .0001)
|
||||||
|
coefficient_keys = ("gd", "c0", "cg", "cv", "threshold", "reset", "seed_volt")
|
||||||
|
_check(all(float(compiled_coefficients[key]).hex() == float(baseline_coefficients[key]).hex()
|
||||||
|
for key in coefficient_keys), "Compiled Brian coefficients differ from sealed AF")
|
||||||
|
_check(last_complete_tick == -1 and worker.tick == 0 and not records["rows"] and not request_seen.any(),
|
||||||
|
"Zero-duration compilation unexpectedly advanced state")
|
||||||
|
network.run(steps * .1 * b2.ms, namespace={})
|
||||||
|
_save(out_dir / "generated-code.json", ae._code_records(network))
|
||||||
|
worker_status = worker.finish(steps)
|
||||||
|
worker = None
|
||||||
|
|
||||||
|
_check(last_complete_tick == steps - 1 and np.all(request_seen == 1) and np.all(apl_seen == 1), "Incomplete trial")
|
||||||
|
_check(records["peek_calls"] == records["advance_calls"] == steps, "Incomplete queue audit")
|
||||||
|
_check(total_events == int(spikes.num_spikes) and np.array_equal(total_counts, np.asarray(spikes.count[:])),
|
||||||
|
"Sparse events disagree with original SpikeMonitor")
|
||||||
|
_check(np.array_equal(request_count, applicable_count + rejected_count), "Incomplete request accounting")
|
||||||
|
_check(np.all(np.asarray(neu.rfc[:] / b2.ms) == float(parameters["t_rfc"] / b2.ms)), "Author refractory duration changed")
|
||||||
|
for begin in range(0, edges, width):
|
||||||
|
stop = min(edges, begin + width)
|
||||||
|
_check(np.array_equal(np.asarray(syn.w_[begin:stop]).view(np.uint64), effective[begin:stop].view(np.uint64)),
|
||||||
|
"Effective synaptic weights changed during the trial")
|
||||||
|
event_values = np.memmap(out_dir / "events.bin", dtype=EVENT_DTYPE, mode="r", shape=(total_events,)) if total_events else np.empty(0, EVENT_DTYPE)
|
||||||
|
_check((out_dir / "events.bin").stat().st_size == total_events * 8, "Sparse event byte count mismatch")
|
||||||
|
for begin in range(0, total_events, width):
|
||||||
|
stop = min(total_events, begin + width)
|
||||||
|
spike_local = np.asarray(spikes.i[begin:stop], dtype=np.int32)
|
||||||
|
np.testing.assert_array_equal(event_values["neuron_idx"][begin:stop], nodes[spike_local])
|
||||||
|
times = np.rint(np.asarray(spikes.t[begin:stop] / b2.second) / .0001).astype(np.int32)
|
||||||
|
np.testing.assert_array_equal(event_values["step"][begin:stop], times)
|
||||||
|
_budget(budget_root, budget_limit, total_events * 8 + n * 24 + (8 << 20))
|
||||||
|
with (out_dir / "state.npz").open("xb") as handle:
|
||||||
|
np.savez_compressed(handle, step=event_values["step"], neuron_idx=event_values["neuron_idx"],
|
||||||
|
counts=total_counts, v=v_raw, g=g_raw, ref=final_ref)
|
||||||
|
with (out_dir / "tick-summary.npz").open("xb") as handle:
|
||||||
|
np.savez_compressed(handle, request_count=request_count, applicable_count=applicable_count,
|
||||||
|
rejected_count=rejected_count, spike_count=spike_count,
|
||||||
|
arrival_count=np.asarray([row["count"] for row in records["rows"]], np.int64),
|
||||||
|
accepted_arrival_count=np.asarray([row["accepted_count"] for row in records["rows"]], np.int64))
|
||||||
|
coefficients = ae._coefficients(neu, parameters, b2, .0001)
|
||||||
|
keys = ("gd", "c0", "cg", "cv", "threshold", "reset", "seed_volt")
|
||||||
|
_check(all(float(coefficients[key]).hex() == float(baseline_coefficients[key]).hex() for key in keys),
|
||||||
|
"Actual Brian coefficients differ from sealed AF coefficients")
|
||||||
|
_save(out_dir / "coefficients.json", coefficients)
|
||||||
|
_save(out_dir / "queue-audit.json", {"peek_calls": records["peek_calls"], "advance_calls": records["advance_calls"],
|
||||||
|
"installations": records["installations"], "same_peek_object_returned": True,
|
||||||
|
"original_edge_ids_not_sorted_or_filtered": True, "zero_weight_and_refractory_rejected_edges_retained": True,
|
||||||
|
"post_threshold_pre_synaptic_guard_observed": True, "forwarding_contract": "sealed AE/AF design",
|
||||||
|
"new_unwrapped_repeat_performed": False, "limit": "Current wrapper was not independently rerun without the queue proxy"})
|
||||||
|
for path, expected in ((author_path, AUTHOR_SHA256), (ae_path, AE_SHA256), (af_path, AF_SHA256), (worker_path, worker_hash)):
|
||||||
|
_check(_digest(path) == expected, f"Source changed during the run: {path}")
|
||||||
|
_check(_digest(coefficients_path) == coefficient_hash, "Sealed coefficient reference changed during the run")
|
||||||
|
for directory, hashes in ((graph_dir, graph_hashes), (bundle_dir, bundle_hashes), (case_dir, case_hashes)):
|
||||||
|
for name, expected in hashes.items():
|
||||||
|
_check(_digest(directory / name) == expected, f"Read-only input changed during the run: {name}")
|
||||||
|
for mapped in mapped_files:
|
||||||
|
mapped.flush()
|
||||||
|
_check("torch" not in sys.modules, "Pinned Brian process unexpectedly imported Torch")
|
||||||
|
output_bytes = _budget(budget_root, budget_limit, 1 << 20)
|
||||||
|
summary = {"name": spec["name"], "complete": True, "precision": "float64", "APL_precision": "float32",
|
||||||
|
"backend": "shared-APL-component closed-loop Brian2 oracle", "steps": steps, "completed_ticks": last_complete_tick + 1,
|
||||||
|
"nodes": n, "edges": edges, "spikes": total_events, "requests": int(request_count.sum()),
|
||||||
|
"applicable_requests": int(applicable_count.sum()), "ref_rejected_requests": int(rejected_count.sum()),
|
||||||
|
"APL_fast_edges_zeroed": mask_count, "APL_worker_exit_status": worker_status, "APL_worker_ticks": steps,
|
||||||
|
"apl_fast_edges_zeroed": mask_count, "effective_weights_raw_sha256": effective_hasher.hexdigest(),
|
||||||
|
"kc_targets_present": len(kc_local),
|
||||||
|
"candidate_trace_used_as_input": False, "independent_CPU_all_components_claim": False,
|
||||||
|
"history_recorded": record_history, "single_continuous_run": True, "no_training": True, "no_poi": True,
|
||||||
|
"source_and_inputs_unchanged": True, "pass_all": True,
|
||||||
|
"pass_all_scope": "Oracle construction, protocol and internal self-checks only; candidate comparison is a separate gate",
|
||||||
|
"scope": "Only this fixed trajectory; legacy Torch APL is a shared numerical component, not an independent CPU APL implementation",
|
||||||
|
"output_budget_bytes": budget_limit, "output_bytes_before_summary": output_bytes,
|
||||||
|
"state_hashes_sha256": _digest(out_dir / "tick-state-hashes.jsonl"), "queue_sha256": _digest(out_dir / "queue.jsonl"),
|
||||||
|
"events_sha256": _digest(out_dir / "events.bin"), "weights_sha256": _digest(out_dir / "weights.npy")}
|
||||||
|
_save(out_dir / "summary.json", summary)
|
||||||
|
return summary
|
||||||
|
except Exception as error:
|
||||||
|
for mapped in mapped_files:
|
||||||
|
mapped.flush()
|
||||||
|
_save(out_dir / "error.json", {"complete": False, "last_complete_tick": last_complete_tick,
|
||||||
|
"type": type(error).__name__, "message": str(error), "partial_files_preserved": True,
|
||||||
|
"inputs_or_duration_adjusted": False})
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
if worker is not None:
|
||||||
|
worker.abort()
|
||||||
|
if saved_preferences is not None:
|
||||||
|
for key, value in saved_preferences.items():
|
||||||
|
b2.prefs[key] = value
|
||||||
|
b2.defaultclock.dt = old_dt
|
||||||
|
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
"""Preregister exact legacy APL data and unmodified fixed CAL requests."""
|
||||||
|
from datetime import datetime,timezone
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import yaml
|
||||||
|
from context import ROOT,MODEL,EXP,AF_MODEL,AF_EXP,AD_EXP,CFG,save,digest,sources,integrity,budget
|
||||||
|
|
||||||
|
def arr(path,value):
|
||||||
|
with Path(path).open('xb') as f:np.save(f,value,allow_pickle=False)
|
||||||
|
|
||||||
|
def graph(folder,nodes,full):
|
||||||
|
folder.mkdir();nodes=np.asarray(nodes,np.int32);ptr,dst,src,raw,base=full
|
||||||
|
if len(nodes)==CFG['neurons']:ids=np.arange(len(dst),dtype=np.int64)
|
||||||
|
else:
|
||||||
|
ids=np.concatenate([np.arange(ptr[s],ptr[s+1],dtype=np.int64) for s in nodes])
|
||||||
|
ids=ids[np.isin(dst[ids],nodes)]
|
||||||
|
lookup=np.full(CFG['neurons'],-1,np.int32);lookup[nodes]=np.arange(len(nodes),dtype=np.int32)
|
||||||
|
ss,dd=lookup[src[ids]],lookup[dst[ids]];pp=np.r_[np.int64(0),np.bincount(ss,minlength=len(nodes)).cumsum(dtype=np.int64)]
|
||||||
|
for name,value in dict(nodes=nodes,edge_id=ids,src=ss,dst=dd,ptr=pp,signed_raw=raw[ids],weights=base[ids]).items():arr(folder/(name+'.npy'),value)
|
||||||
|
pd.DataFrame({'local_index':np.arange(len(nodes),dtype=np.int32)},index=pd.Index(nodes,name='global_neuron_idx')).to_csv(folder/'completeness.csv')
|
||||||
|
pd.DataFrame({'Presynaptic_Index':ss,'Postsynaptic_Index':dd,'Excitatory x Connectivity':raw[ids],'edge_id':ids},copy=False).to_parquet(folder/'connectivity.parquet',index=False)
|
||||||
|
save(folder/'audit.json',dict(nodes=len(nodes),edges=len(ids),canonical_original_edge_ids=True,anatomical_weights_not_modified=True,
|
||||||
|
effective_APL_zeroing='Only in new runtime clone, never these original weight files'))
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
def case(name,kind,steps,nodes,graphdir,requests,initial=None,extra=None):
|
||||||
|
folder=EXP/'cases'/name;folder.mkdir()
|
||||||
|
model=json.loads((AD_EXP/'protocol/preregistered.json').read_text())['config']['model']
|
||||||
|
spec=dict(name=name,kind=kind,steps=steps,dt_ms=.1,duration_ms=steps*.1,model=model,
|
||||||
|
graph_dir=str(graphdir),apl_bundle_dir=str(EXP/'apl-bundle'),apl=CFG['apl'],record_history=kind=='fixture',
|
||||||
|
coefficients_path=str(AF_EXP/'oracle/no_input/coefficients.json'),
|
||||||
|
science_python=str(ROOT/'models/male-cns-lif/.venv/bin/python'),legacy_apl_worker=str(MODEL/'legacy_apl_worker.py'),
|
||||||
|
budget_root=str(EXP),output_budget_bytes=CFG['output_budget_bytes'],precision='float64',apl_precision='float32',training=False)
|
||||||
|
if extra:spec.update(extra)
|
||||||
|
requests=np.asarray(requests,dtype=np.int32).reshape(-1,2)
|
||||||
|
if len(requests):
|
||||||
|
requests=requests[np.lexsort((requests[:,1],requests[:,0]))]
|
||||||
|
assert len(np.unique(requests.astype(np.int64)[:,0]*CFG['neurons']+requests[:,1]))==len(requests)
|
||||||
|
assert requests[:,0].min()>=0 and requests[:,0].max()<steps and np.isin(requests[:,1],nodes).all()
|
||||||
|
with (folder/'requests.npz').open('xb') as f:np.savez_compressed(f,tick=requests[:,0],neuron_idx=requests[:,1])
|
||||||
|
if kind=='fixture':
|
||||||
|
v=np.full(len(nodes),model['resting_potential_mv'],np.float64);g=np.zeros(len(nodes),np.float64)
|
||||||
|
if initial:
|
||||||
|
for node,value in initial.get('v',{}).items():v[np.flatnonzero(nodes==node)[0]]=value
|
||||||
|
for node,value in initial.get('g',{}).items():g[np.flatnonzero(nodes==node)[0]]=value
|
||||||
|
with (folder/'arrays.npz').open('xb') as f:np.savez_compressed(f,initial_v_mv=v,initial_g_mv=g)
|
||||||
|
save(folder/'spec.json',spec)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
assert not (EXP/'protocol/preregistered.json').exists()
|
||||||
|
assert all(not (EXP/d).exists() or not any((EXP/d).iterdir()) for d in ('protocol','graphs','apl-bundle','cases','gpu','oracle'))
|
||||||
|
assert shutil.disk_usage(EXP.parent).free>30*1024**3
|
||||||
|
for d in ('protocol','apl-bundle','graphs','cases','gpu','oracle','component-audit','regression','calibration','audit','extension-build','logs'):(EXP/d).mkdir(parents=True,exist_ok=True)
|
||||||
|
can=ROOT/'datasets/male-cns-v1.0/processed/neuron-only';legacy=ROOT/'models/male-cns-lif';lp=legacy/'olfactory-grounding-v1/phase4l.yaml'
|
||||||
|
lock=ROOT/'experiments/phase4j-mb-physiology-repair/calibration/locked-parameters.json'
|
||||||
|
files=[AF_MODEL/'manifest.json',AF_EXP/'manifest.json',AF_EXP/'oracle/no_input/coefficients.json',
|
||||||
|
legacy/'deterministic-runtime-v2/phase4p_revalidate.py',lp,lock,can/'neuron-index/unified-metadata.parquet',can/'gpu/csr-weights.int64.npy',
|
||||||
|
legacy/'author-runtime-lab-v1/author_ext.cpp',legacy/'author-runtime-lab-v1/author_ext.cu',legacy/'author-runtime-lab-v1/gpu_backend.py',
|
||||||
|
legacy/'author-runtime-lab-v1/oracle_stress.py',AD_EXP/'external-resources/model.py',AF_MODEL/'oracle_full.py']
|
||||||
|
lroot=ROOT/'experiments/phase4l-olfactory-grounding'
|
||||||
|
files += [lroot/'odor-encoder'/x for x in ('frozen-odor-panel.parquet','mapped-glomerular-vectors.npz','selection.json')]
|
||||||
|
files += [lroot/'receptor-mapping/olfactory-mapping.parquet']
|
||||||
|
prior=ROOT/'experiments/phase4ag-author-apl'
|
||||||
|
files += [prior/'manifest.json',ROOT/'models/male-cns-lif/author-apl-lab-v1/manifest.json']
|
||||||
|
save(EXP/'protocol/preregistered.json',dict(timestamp_utc=datetime.now(timezone.utc).isoformat(),sources=sources(),config=CFG,
|
||||||
|
inputs=[dict(path=str(p.relative_to(ROOT)),sha256=digest(p)) for p in files],before_any_trajectory=True,
|
||||||
|
parent_commit=subprocess.check_output(['git','-C',str(ROOT),'rev-parse','HEAD'],text=True).strip()))
|
||||||
|
save(EXP/'regression/old-integrity-before.json',integrity())
|
||||||
|
science_entry=ROOT/'models/male-cns-lif/.venv/bin/python'
|
||||||
|
command=[str(science_entry),'-B','-c',
|
||||||
|
'import sys,json,importlib.util; print(json.dumps(dict(executable=sys.executable,prefix=sys.prefix,base_prefix=sys.base_prefix,numpy_visible=importlib.util.find_spec("numpy") is not None,torch_visible=importlib.util.find_spec("torch") is not None)))']
|
||||||
|
environment=json.loads(subprocess.check_output(command,text=True))
|
||||||
|
assert environment['executable']==str(science_entry) and environment['prefix']==str(science_entry.parent.parent)
|
||||||
|
assert environment['prefix']!=environment['base_prefix'] and environment['numpy_visible'] and environment['torch_visible']
|
||||||
|
save(EXP/'protocol/execution-preflight.json',dict(command=command,observed=environment,
|
||||||
|
before_any_trajectory=True,torch_imported=False,CUDA_initialized=False))
|
||||||
|
locked=json.loads(lock.read_text());assert locked['parameters_locked'] and locked['calibration_only']
|
||||||
|
assert {k:locked['selected'][k] for k in ('gain','normalization','tau_ms')}==CFG['apl']
|
||||||
|
meta=pd.read_parquet(can/'neuron-index/unified-metadata.parquet').sort_values('neuron_idx').reset_index(drop=True)
|
||||||
|
assert len(meta)==CFG['neurons'] and np.array_equal(meta.neuron_idx,np.arange(CFG['neurons']))
|
||||||
|
cls=meta.annotation_class.fillna('').astype(str).to_numpy();typ=meta.annotation_type.fillna('').astype(str).to_numpy()
|
||||||
|
kc=np.flatnonzero(cls=='Kenyon_Cell').astype(np.int32);pn=np.flatnonzero(cls=='ALPN').astype(np.int32);apl=np.flatnonzero(typ=='APL').astype(np.int32)
|
||||||
|
assert len(kc)==4064 and len(apl)==2
|
||||||
|
fg=AF_EXP/'graph';ptr=np.load(fg/'ptr.npy',mmap_mode='r');dst=np.load(fg/'dst.npy',mmap_mode='r');src=np.load(fg/'src.npy',mmap_mode='r')
|
||||||
|
signed=np.load(fg/'signed_raw.npy',mmap_mode='r');base=np.load(AF_EXP/'oracle/no_input/weights.npy',mmap_mode='r');raw=np.load(can/'gpu/csr-weights.int64.npy',mmap_mode='r')
|
||||||
|
assert len(dst)==CFG['edges'] and int(raw.sum())==CFG['raw_weight_sum']
|
||||||
|
aplout=np.isin(src,apl);aplids=np.flatnonzero(aplout).astype(np.int64);assert len(aplids)==5845
|
||||||
|
I=np.zeros((2,len(meta)),np.float32);O=np.zeros((2,len(kc)),np.float32)
|
||||||
|
alook={int(v):i for i,v in enumerate(apl)};kl=np.full(len(meta),-1,np.int32);kl[kc]=np.arange(len(kc),dtype=np.int32)
|
||||||
|
allowed=np.isin(src,np.r_[kc,pn])&np.isin(dst,apl)
|
||||||
|
for eid in np.flatnonzero(allowed):I[alook[int(dst[eid])],int(src[eid])]+=float(raw[eid])
|
||||||
|
for eid in np.flatnonzero(aplout&np.isin(dst,kc)):O[alook[int(src[eid])],kl[dst[eid]]]+=float(raw[eid])
|
||||||
|
iscale=float(I[I>0].sum()/np.count_nonzero(np.any(I>0,axis=0)));oscale=float(O[O>0].mean());bundle=EXP/'apl-bundle'
|
||||||
|
for name,value in dict(input_matrix=I/iscale,output_matrix=O/oscale,input_raw=I,output_raw=O,kc_globals=kc,pn_globals=pn,apl_globals=apl,apl_out_ids=aplids).items():arr(bundle/(name+'.npy'),value)
|
||||||
|
save(bundle/'scales.json',dict(input_scale=iscale,output_scale=oscale))
|
||||||
|
save(bundle/'provenance.json',dict(canonical_root=str(can),source=str(legacy/'deterministic-runtime-v2/phase4p_revalidate.py'),source_sha256=digest(legacy/'deterministic-runtime-v2/phase4p_revalidate.py'),
|
||||||
|
parameters=CFG['apl'],lock_file=str(lock),lock_sha256=digest(lock),full_dimensions=[list(I.shape),list(O.shape)],
|
||||||
|
APL=len(apl),KC=len(kc),ALPN=len(pn),APL_fast_edges=len(aplids),APL_nonKC_edges=int(np.count_nonzero(aplout&~np.isin(dst,kc))),
|
||||||
|
APL_nonKC_contacts=int(raw[aplout&~np.isin(dst,kc)].sum()),normalization_recomputed_in_original_order=True,
|
||||||
|
raw_files_modified=False))
|
||||||
|
full=(ptr,dst,src,signed,base);fullnodes=graph(EXP/'graphs/full',np.arange(len(meta),dtype=np.int32),full)
|
||||||
|
pscore=I.sum(axis=0);pnrank=pn[np.lexsort((pn,-pscore[pn]))];kscore=O.sum(axis=0);kcrank=kc[np.lexsort((kc,-kscore))]
|
||||||
|
candidates=np.flatnonzero(np.isin(src,pn)&np.isin(dst,kc));best=int(candidates[np.argmax(raw[candidates])]);pairpn=int(src[best])
|
||||||
|
pe=np.arange(ptr[pairpn],ptr[pairpn+1],dtype=np.int64);pe=pe[np.isin(dst[pe],kc)];pe=pe[np.lexsort((dst[pe],-raw[pe]))]
|
||||||
|
collision_kc=np.unique(dst[pe[:3]]);assert len(collision_kc)==3
|
||||||
|
nonkc=aplids[~np.isin(dst[aplids],kc)];nonkc_target=int(dst[nonkc[np.argmax(raw[nonkc])]])
|
||||||
|
nodes=np.unique(np.r_[apl,pnrank[:16],kcrank[:16],pairpn,collision_kc,nonkc_target,[1197,1381,1511,82312,133666]]).astype(np.int32)
|
||||||
|
fixturegraph=EXP/'graphs/fixtures';graph(fixturegraph,nodes,full)
|
||||||
|
p=int(pnrank[0]);k=int(kcrank[0]);kc1,kc2,kc3=map(int,collision_kc)
|
||||||
|
designs=[('zero',100,[],None),('pn_pulse',300,[(0,p)],None),
|
||||||
|
('kc_ref_boundary',100,[(t,k) for t in (0,1,21,22,23,44)],None),
|
||||||
|
('two_sources',300,[(t,n) for t in (0,22,44,66,88) for n in (p,k)],None),
|
||||||
|
('arrival_collision',120,[(0,pairpn),(0,kc1),(18,kc2),(21,kc1)],None),
|
||||||
|
('natural_request',100,[(0,k)],dict(v={k:-44.0})),
|
||||||
|
('apl_only',100,[(0,int(a)) for a in apl],None),
|
||||||
|
('high_fanin',400,[(t,int(n)) for t in (0,22,44) for n in nodes if pscore[n]>0],dict(g={k:.123}))]
|
||||||
|
assert [v[0] for v in designs]==CFG['fixtures']
|
||||||
|
for name,steps,requests,initial in designs:case(name,'fixture',steps,nodes,fixturegraph,requests,initial)
|
||||||
|
meta.iloc[nodes][['neuron_idx','body_id','annotation_class','annotation_type','neurotransmitter']].to_csv(EXP/'protocol/fixture-identities.csv',index=False)
|
||||||
|
save(EXP/'protocol/fixture-selection.json',dict(pn=p,kc=k,pair_PN=pairpn,arrival_KCs=collision_kc.tolist(),real_PN_KC_edge=best,
|
||||||
|
nonKC_APL_target=nonkc_target,method='Static raw-count ranks and exact metadata; retain ALL existing induced edges and full APL matrices/norms',runtime_selection=False))
|
||||||
|
os.environ['CUDA_VISIBLE_DEVICES']=CFG['gpu_uuid'];sys.path.insert(0,str(legacy));sys.path.insert(0,str(legacy/'deterministic-runtime-v2'))
|
||||||
|
sys.path.insert(0,str(legacy/'terminal-scope-diagnostic-v1'));from diagnostic import queues
|
||||||
|
queues()
|
||||||
|
import torch
|
||||||
|
from phase4p_revalidate import door_inputs,make_drive
|
||||||
|
oc,panel,vectors,selection,mapping=door_inputs();cal=panel[panel.split=='calibration'].copy();assert len(panel)==12 and len(cal)==6
|
||||||
|
assert oc['odor_encoder']['evaluation_seeds']==CFG['calibration']['seeds']
|
||||||
|
assert float(oc['odor_encoder']['duration_ms'])==CFG['calibration']['duration_ms']
|
||||||
|
cal.to_parquet(EXP/'protocol/calibration-panel.parquet',index=False);calrecords=[]
|
||||||
|
for mode in CFG['calibration']['modes']:
|
||||||
|
for oi,(_,odor) in enumerate(cal.iterrows()):
|
||||||
|
targets,rates=make_drive(oc,panel,vectors,selection,mapping,odor.odor_id,mode)
|
||||||
|
assert len(np.unique(targets))==len(targets),'Original encoder emits duplicate PN targets; audit instead of silently merging'
|
||||||
|
rates=np.asarray(rates,np.float32);steps=round(CFG['calibration']['duration_ms']/.1)
|
||||||
|
for seed in CFG['calibration']['seeds']:
|
||||||
|
gen=torch.Generator(device='cuda');gen.manual_seed(seed)
|
||||||
|
original_probability=rates*.1/1000.0
|
||||||
|
explicit_probability=rates*np.float32(.1)/np.float32(1000.)
|
||||||
|
assert original_probability.dtype==np.float32 and np.array_equal(original_probability.view(np.uint32),explicit_probability.view(np.uint32))
|
||||||
|
probs=torch.as_tensor(original_probability,dtype=torch.float32,device='cuda')
|
||||||
|
forced=(torch.rand((steps,len(targets)),generator=gen,device='cuda')<probs[None,:]).cpu().numpy()
|
||||||
|
tt,cc=np.nonzero(forced);req=np.column_stack([tt,targets[cc]]).astype(np.int32)
|
||||||
|
name=f'cal-{mode}-{oi:02d}-s{seed}'
|
||||||
|
case(name,'calibration',steps,fullnodes,EXP/'graphs/full',req,extra=dict(odor_id=str(odor.odor_id),odor_name=str(odor.odor_name),
|
||||||
|
mode=mode,seed=seed,odor_index=oi,expected_external_events=float(rates.sum())*steps*.1/1000.,target_count=len(targets),rate_sum_hz=float(rates.sum())))
|
||||||
|
with (EXP/'cases'/name/'pn-drive.npz').open('xb') as f:np.savez_compressed(f,targets=targets,rates_hz=rates)
|
||||||
|
calrecords.append(dict(name=name,mode=mode,odor_index=oi,odor_id=str(odor.odor_id),seed=seed,requests=len(req),rates_sum=float(rates.sum())))
|
||||||
|
save(EXP/'protocol/calibration-cases.json',calrecords)
|
||||||
|
save(EXP/'protocol/encoder-audit.json',dict(panel_count=12,cal_count=6,median_mapped_response_sum=float(np.median(panel.mapped_response_sum)),
|
||||||
|
target_rng_column_order='Original pn_drive, no sorting before torch.rand',seeds=CFG['calibration']['seeds'],
|
||||||
|
requested_before_any_dynamics=True,formal_AB_run=False,heldout_run=False,torch=torch.__version__,numpy=np.__version__,
|
||||||
|
generation='Original rates*.1/1000 float32 GPU Bernoulli, independent per-case original seed'))
|
||||||
|
revision=[]
|
||||||
|
for folder in sorted((EXP/'cases').iterdir()):
|
||||||
|
with np.load(folder/'requests.npz',allow_pickle=False) as new,np.load(prior/'cases'/folder.name/'requests.npz',allow_pickle=False) as old:
|
||||||
|
assert new.files==old.files and all(new[key].dtype==old[key].dtype and np.array_equal(new[key],old[key]) for key in old.files)
|
||||||
|
revision.append(dict(case=folder.name,sparse_request_arrays_exact=True))
|
||||||
|
save(EXP/'protocol/revision-input-equivalence.json',dict(prior_experiment=str(prior),cases=revision,
|
||||||
|
input_arrays_unchanged=True,reason='Execution-only venv invocation fix; no trajectory outcome used for input choice'))
|
||||||
|
save(EXP/'protocol/prepared-hashes.json',[dict(path=str(p.relative_to(EXP)),bytes=p.stat().st_size,sha256=digest(p))
|
||||||
|
for d in ('graphs','apl-bundle','cases','protocol') for p in sorted((EXP/d).rglob('*')) if p.is_file() and p.name!='prepared-hashes.json'])
|
||||||
|
budget();print('PREPARED8 fixtures and60 fixed CAL inputs; no trajectories; frozen integrity PASS',flush=True)
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
"""A fresh process per declared case; no concurrent scientific GPU jobs."""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
from context import ROOT,MODEL,EXP,CFG,check,budget
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser=argparse.ArgumentParser()
|
||||||
|
parser.add_argument('backend',choices=['gpu','oracle','component'])
|
||||||
|
parser.add_argument('case')
|
||||||
|
parser.add_argument('--repeat',type=int,default=0)
|
||||||
|
args=parser.parse_args()
|
||||||
|
assert '/' not in args.case and '..' not in args.case and 0<=args.repeat<3
|
||||||
|
check();budget()
|
||||||
|
os.environ['CUDA_VISIBLE_DEVICES']=CFG['gpu_uuid']
|
||||||
|
os.environ['CUDA_HOME']='/usr/local/cuda'
|
||||||
|
os.environ['PATH']=str(ROOT/'models/male-cns-lif/.venv/bin')+':/usr/local/cuda/bin:'+os.environ['PATH']
|
||||||
|
os.environ['MAX_JOBS']='2';os.environ['TORCH_CUDA_ARCH_LIST']='8.9'
|
||||||
|
# The pinned Brian environment intentionally has neither Torch nor PyYAML.
|
||||||
|
# Keep this preflight standard-library-only; never install into that env.
|
||||||
|
for port in (8188,8189,8190):
|
||||||
|
with urllib.request.urlopen(f'http://192.168.10.51:{port}/queue',timeout=5) as response:
|
||||||
|
queue=json.load(response)
|
||||||
|
assert not queue['queue_running'] and not queue['queue_pending'],'ComfyUI busy: defer, never evict'
|
||||||
|
case=EXP/'cases'/args.case
|
||||||
|
assert case.is_dir()
|
||||||
|
out=EXP/'gpu'/f'{args.case}-r{args.repeat}'
|
||||||
|
if args.backend=='gpu':
|
||||||
|
from gpu_apl import run_gpu
|
||||||
|
result=run_gpu(case,out,EXP/'extension-build')
|
||||||
|
elif args.backend=='oracle':
|
||||||
|
assert args.repeat==0
|
||||||
|
from oracle_apl import run_case
|
||||||
|
result=run_case(case,EXP/'oracle'/args.case)
|
||||||
|
else:
|
||||||
|
assert args.repeat==0
|
||||||
|
from validate_components import validate
|
||||||
|
result=validate(out,EXP/'apl-bundle',EXP/'component-audit'/(args.case+'.json'))
|
||||||
|
budget()
|
||||||
|
print(json.dumps(dict(backend=args.backend,case=args.case,repeat=args.repeat,
|
||||||
|
complete=result.get('complete'),pass_all=result.get('pass_all')),allow_nan=False),flush=True)
|
||||||
|
if not result.get('pass_all',False):raise SystemExit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
"""Ordered numerical gates before any full CAL; never tune from outcomes."""
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
from context import ROOT,MODEL,EXP,CFG,check,save,budget
|
||||||
|
|
||||||
|
SCIENCE=ROOT/'models/male-cns-lif/.venv/bin/python'
|
||||||
|
ORACLE=ROOT/'experiments/phase4ad-author-semantics/environment/.venv/bin/python'
|
||||||
|
|
||||||
|
|
||||||
|
def child(backend,name,repeat=0):
|
||||||
|
log=EXP/'logs'/f'{backend}-{name}-r{repeat}.log'
|
||||||
|
cmd=[str(ORACLE if backend=='oracle' else SCIENCE),'-B',str(MODEL/'run_case.py'),backend,name,'--repeat',str(repeat)]
|
||||||
|
print('START',backend,name,repeat,flush=True);t0=time.perf_counter()
|
||||||
|
with log.open('x',encoding='utf-8') as f:
|
||||||
|
result=subprocess.run(cmd,stdout=f,stderr=subprocess.STDOUT,timeout=1800,check=False)
|
||||||
|
print('FINISH',backend,name,repeat,'exit',result.returncode,'wall',round(time.perf_counter()-t0,2),flush=True)
|
||||||
|
if result.returncode:raise RuntimeError(f'{backend} {name} failed; inspect {log}')
|
||||||
|
|
||||||
|
|
||||||
|
def gate_case(name,repeats):
|
||||||
|
from compare import compare,compare_gpu_repeats
|
||||||
|
child('gpu',name)
|
||||||
|
for r in range(1,repeats):child('gpu',name,r)
|
||||||
|
child('oracle',name)
|
||||||
|
result=compare(EXP/'cases'/name,EXP/'gpu'/(name+'-r0'),EXP/'oracle'/name,EXP/'audit'/('compare-'+name+'.json'))
|
||||||
|
assert result['pass_all'],f'Closed-loop exact comparison failed: {name}; no later CAL permitted'
|
||||||
|
for r in range(1,repeats):
|
||||||
|
report=compare_gpu_repeats(EXP/'gpu'/(name+'-r0'),EXP/'gpu'/f'{name}-r{r}',EXP/'audit'/f'repeat-{name}-r{r}.json')
|
||||||
|
assert report['pass_all'],f'Exact GPU repeat failed: {name}'
|
||||||
|
child('component',name)
|
||||||
|
return dict(case=name,pass_all=True,gpu_repeats=repeats)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser=argparse.ArgumentParser();parser.add_argument('stage',choices=['fixtures','probes','calibration']);args=parser.parse_args()
|
||||||
|
check();budget();receipt=EXP/'audit'/(args.stage+'-gate.json');assert not receipt.exists()
|
||||||
|
try:
|
||||||
|
if args.stage=='fixtures':
|
||||||
|
rows=[gate_case(n,CFG['fixture_repeats']) for n in CFG['fixtures']]
|
||||||
|
save(receipt,dict(pass_all=True,cases=rows,scope='Fixed real-edge induced fixtures only'))
|
||||||
|
elif args.stage=='probes':
|
||||||
|
assert json.loads((EXP/'audit/fixtures-gate.json').read_text())['pass_all']
|
||||||
|
rows=[gate_case(n,1) for n in CFG['calibration']['full_oracle_probes']]
|
||||||
|
save(receipt,dict(pass_all=True,cases=rows,scope='Only two original first-CAL fixed fullgraph trajectories'))
|
||||||
|
else:
|
||||||
|
assert json.loads((EXP/'audit/fixtures-gate.json').read_text())['pass_all']
|
||||||
|
assert json.loads((EXP/'audit/probes-gate.json').read_text())['pass_all']
|
||||||
|
records=json.loads((EXP/'protocol/calibration-cases.json').read_text());assert len(records)==60
|
||||||
|
probes=CFG['calibration']['full_oracle_probes']
|
||||||
|
for rec in records:
|
||||||
|
if rec['name'] not in probes:child('gpu',rec['name'])
|
||||||
|
if rec['seed']==CFG['calibration']['seeds'][0]:child('gpu',rec['name'],1)
|
||||||
|
from calibration import summarize
|
||||||
|
result=summarize()
|
||||||
|
save(receipt,dict(pass_all=result['pass_all'],scope='Complete original six-CAL representation gate, not heldout or learning',summary='calibration/summary.json'))
|
||||||
|
if not result['pass_all']:raise SystemExit(2)
|
||||||
|
except Exception as e:
|
||||||
|
save(EXP/'audit'/('stopped-'+args.stage+'.json'),dict(stage=args.stage,type=type(e).__name__,message=str(e),traceback=traceback.format_exc(),
|
||||||
|
later_stages_not_permitted=True,partial_outputs_preserved=True,parameters_changed=False))
|
||||||
|
raise
|
||||||
|
budget()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
"""Local, synthetic tests only: no CUDA, scientific trajectories, or heldout data."""
|
||||||
|
import copy
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from calibration import (ORIGINAL_MODES, ORIGINAL_SEEDS, ORIGINAL_CAL_IDS,
|
||||||
|
APL_FILES, STATE_DTYPES, arrays_bitwise_equal, evaluate_gates, exact_repeat, pair_metrics,
|
||||||
|
sample_cv, summarize_mode, validate_inventory, validate_state)
|
||||||
|
|
||||||
|
|
||||||
|
GATES = {"sparse_min_fraction": .03, "sparse_max_fraction": .09,
|
||||||
|
"minimum_separable_odor_pairs": 3, "max_fraction_strict": .5, "min_fraction_strict": 0.,
|
||||||
|
"same_jaccard_gt_between": True, "between_euclidean_gt_within": True,
|
||||||
|
"both_modes_required": True, "finite_required": True, "repeat_exact_required": True}
|
||||||
|
|
||||||
|
|
||||||
|
def synthetic_runs(silent=False):
|
||||||
|
result = {}
|
||||||
|
for mode in ORIGINAL_MODES:
|
||||||
|
for odor in range(6):
|
||||||
|
for seed in ORIGINAL_SEEDS:
|
||||||
|
counts = np.zeros(1000, dtype=np.int32)
|
||||||
|
if not silent:
|
||||||
|
counts[odor * 50:(odor + 1) * 50] = 1
|
||||||
|
result[(mode, str(odor), seed)] = {"kc_counts": counts,
|
||||||
|
"expected_external_events": 10., "external_events": 0 if silent else 10}
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class CalibrationTests(unittest.TestCase):
|
||||||
|
def test_complete_gate_and_original_pair_counts(self):
|
||||||
|
summary = summarize_mode(ORIGINAL_MODES[0], list(map(str, range(6))), ORIGINAL_SEEDS, synthetic_runs(), GATES)
|
||||||
|
self.assertTrue(summary["gate"])
|
||||||
|
self.assertEqual(summary["within_distance_count"], 60)
|
||||||
|
self.assertEqual(summary["between_distance_count"], 75)
|
||||||
|
self.assertEqual(summary["pair_count"], 15)
|
||||||
|
self.assertEqual(summary["pairwise_separation_pass_count"], 15)
|
||||||
|
self.assertTrue(all(row["within_distance_count"] == 20 and row["between_distance_count"] == 5 for row in summary["pairs"]))
|
||||||
|
|
||||||
|
def test_silent_is_not_pass(self):
|
||||||
|
summary = summarize_mode(ORIGINAL_MODES[0], list(map(str, range(6))), ORIGINAL_SEEDS, synthetic_runs(True), GATES)
|
||||||
|
self.assertFalse(summary["gate"])
|
||||||
|
self.assertFalse(summary["conditions"]["minimum_strictly_positive"])
|
||||||
|
self.assertFalse(summary["conditions"]["same_jaccard_gt_different"])
|
||||||
|
self.assertFalse(summary["conditions"]["different_euclidean_gt_same"])
|
||||||
|
self.assertEqual(summary["pairwise_separation_pass_count"], 0)
|
||||||
|
self.assertIsNone(summary["actual_event_count_cv"])
|
||||||
|
|
||||||
|
def test_every_original_conjunct_is_necessary(self):
|
||||||
|
baseline = summarize_mode(ORIGINAL_MODES[0], list(map(str, range(6))), ORIGINAL_SEEDS, synthetic_runs(), GATES)
|
||||||
|
changes = (("KC_active_fraction_mean", .029), ("KC_active_fraction_mean", .091),
|
||||||
|
("KC_active_fraction_max", .5), ("KC_active_fraction_min", 0.),
|
||||||
|
("same_odor_jaccard_mean", baseline["different_odor_jaccard_mean"]),
|
||||||
|
("different_odor_euclidean_mean", baseline["same_odor_euclidean_mean"]),
|
||||||
|
("pairwise_separation_pass_count", 2))
|
||||||
|
for key, value in changes:
|
||||||
|
with self.subTest(key=key, value=value):
|
||||||
|
modified = dict(baseline, **{key: value})
|
||||||
|
self.assertFalse(all(evaluate_gates(modified, GATES).values()))
|
||||||
|
for value in (.03, .09):
|
||||||
|
self.assertTrue(evaluate_gates(dict(baseline, KC_active_fraction_mean=value), GATES)["mean_sparsity_in_closed_interval"])
|
||||||
|
|
||||||
|
def test_pair_specific_not_global_baseline(self):
|
||||||
|
runs = synthetic_runs()
|
||||||
|
mode = ORIGINAL_MODES[0]
|
||||||
|
for odor in range(6):
|
||||||
|
for index, seed in enumerate(ORIGINAL_SEEDS):
|
||||||
|
counts = np.array([index + odor * 100] if odor < 2 else [10000 * odor + index * 1000], dtype=np.int32)
|
||||||
|
runs[(mode, str(odor), seed)]["kc_counts"] = counts
|
||||||
|
summary = summarize_mode(mode, list(map(str, range(6))), ORIGINAL_SEEDS, runs, GATES)
|
||||||
|
first_pair = summary["pairs"][0]
|
||||||
|
self.assertEqual(first_pair["within_this_pair_mean"], 2.)
|
||||||
|
self.assertEqual(first_pair["between_same_seed_mean"], 100.)
|
||||||
|
self.assertTrue(first_pair["gate"])
|
||||||
|
self.assertGreater(summary["same_odor_euclidean_mean"], 100.)
|
||||||
|
|
||||||
|
def test_original_metric_zero_and_count_semantics(self):
|
||||||
|
zero = np.zeros(3, dtype=np.int32)
|
||||||
|
self.assertEqual(pair_metrics(zero, zero)["active_jaccard"], 1.)
|
||||||
|
self.assertEqual(pair_metrics(zero, zero)["correlation"], 1.)
|
||||||
|
result = pair_metrics(np.array([2, 0, 0]), np.array([1, 0, 0]))
|
||||||
|
self.assertEqual(result["euclidean_distance"], 1.)
|
||||||
|
self.assertEqual(result["active_jaccard"], 1.)
|
||||||
|
self.assertAlmostEqual(sample_cv([1., 2., 3.]), .5)
|
||||||
|
|
||||||
|
def test_repeat_comparison_is_bits_and_dtype(self):
|
||||||
|
self.assertFalse(arrays_bitwise_equal(np.array([0.], np.float64), np.array([-0.], np.float64)))
|
||||||
|
self.assertFalse(arrays_bitwise_equal(np.array([1], np.int32), np.array([1], np.int64)))
|
||||||
|
self.assertTrue(arrays_bitwise_equal(np.array([1.], np.float32), np.array([1.], np.float32)))
|
||||||
|
|
||||||
|
def test_exact_repeat_covers_all_recorded_semantics(self):
|
||||||
|
first = {"state": {name: np.zeros(1, dtype) for name, dtype in STATE_DTYPES.items()},
|
||||||
|
"apl": {name: np.zeros((1, width), np.float32) for name, width in APL_FILES.items()},
|
||||||
|
"hashes": [{"tick": 0}], "queues": [{"tick": 0}],
|
||||||
|
"requests": [], "component": {"environment": {"tf32": False}}}
|
||||||
|
self.assertTrue(exact_repeat(first, copy.deepcopy(first))["pass_all"])
|
||||||
|
for category in ("state", "apl"):
|
||||||
|
for name in first[category]:
|
||||||
|
bad = copy.deepcopy(first)
|
||||||
|
bad[category][name].flat[0] = 1
|
||||||
|
with self.subTest(category=category, name=name):
|
||||||
|
self.assertFalse(exact_repeat(first, bad)["pass_all"])
|
||||||
|
for key in ("hashes", "queues", "requests", "component"):
|
||||||
|
bad = copy.deepcopy(first)
|
||||||
|
bad[key] = {} if isinstance(first[key], list) else []
|
||||||
|
with self.subTest(key=key):
|
||||||
|
self.assertFalse(exact_repeat(first, bad)["pass_all"])
|
||||||
|
|
||||||
|
def test_raw_state_rejects_nonfinite_duplicate_and_wrong_counts(self):
|
||||||
|
state = {"step": np.array([0], np.int32), "neuron_idx": np.array([1], np.int32),
|
||||||
|
"counts": np.array([0, 1], np.int32), "v": np.zeros(2, np.float64),
|
||||||
|
"g": np.zeros(2, np.float64), "ref": np.zeros(2, np.int32)}
|
||||||
|
validate_state(state, 2, 10)
|
||||||
|
for mutation in ("nan", "counts", "duplicate", "wrong_dtype"):
|
||||||
|
bad = copy.deepcopy(state)
|
||||||
|
if mutation == "nan": bad["g"][0] = np.nan
|
||||||
|
if mutation == "counts": bad["counts"][0] = 1
|
||||||
|
if mutation == "duplicate":
|
||||||
|
bad["step"] = np.array([0, 0], np.int32)
|
||||||
|
bad["neuron_idx"] = np.array([1, 1], np.int32)
|
||||||
|
bad["counts"][1] = 2
|
||||||
|
if mutation == "wrong_dtype": bad["v"] = bad["v"].astype(np.float32)
|
||||||
|
with self.subTest(mutation=mutation), self.assertRaises(ValueError):
|
||||||
|
validate_state(bad, 2, 10)
|
||||||
|
|
||||||
|
def test_inventory_rejects_missing_duplicate_or_heldout_identity(self):
|
||||||
|
odors = sorted(ORIGINAL_CAL_IDS)
|
||||||
|
records = [{"name": f"cal-{mode}-{index:02d}-s{seed}", "mode": mode, "odor_index": index,
|
||||||
|
"odor_id": odors[index], "seed": seed} for mode in ORIGINAL_MODES
|
||||||
|
for index in range(6) for seed in ORIGINAL_SEEDS]
|
||||||
|
cfg = {"calibration": {"modes": list(ORIGINAL_MODES), "seeds": list(ORIGINAL_SEEDS),
|
||||||
|
"duration_ms": 100., "odor_count": 6, "split": "calibration", "repeat_first_seed_each_odor": True}, "gates": GATES}
|
||||||
|
self.assertEqual(validate_inventory(records, cfg), odors)
|
||||||
|
for malformed in (records[:-1], records[:-1] + [records[0]],
|
||||||
|
[dict(row, odor_id="heldout") if row["odor_index"] == 0 else row for row in records]):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
validate_inventory(malformed, cfg)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
"""Local/remote pure protocol tests; no Brian, Torch, GPU or network execution.
|
||||||
|
|
||||||
|
Run with the already-provisioned Python and ``-B test_protocol.py``. The
|
||||||
|
sidecar process is mocked with in-memory stdin and an anonymous stdout pipe.
|
||||||
|
These tests validate transport and declared arithmetic/input contracts, not
|
||||||
|
the scientific trajectory or independent correctness of the Torch component.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import io
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import types
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
HERE = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
|
||||||
|
def load_no_cache(path, name):
|
||||||
|
module = types.ModuleType(name)
|
||||||
|
module.__file__ = str(path)
|
||||||
|
exec(compile(path.read_bytes(), str(path), "exec"), module.__dict__)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
ORACLE = load_no_cache(HERE / "oracle_apl.py", "phase4ag_protocol_oracle")
|
||||||
|
|
||||||
|
|
||||||
|
def handshake(**updates):
|
||||||
|
result = {"ok": True, "protocol": "phase4ag-apl-v1", "n_neurons": 166700,
|
||||||
|
"n_apl": 2, "n_kc": 4064, "dt_ms": .1,
|
||||||
|
"files_sha256": {name: "frozen-test-hash" for name in ORACLE.BUNDLE_FILES},
|
||||||
|
"decay_f32_bits": f"{int(np.float32(math.exp(-.1 / 20.)).view(np.uint32)):08x}",
|
||||||
|
"gain_f32_bits": f"{int(np.float32(.01).view(np.uint32)):08x}"}
|
||||||
|
result.update(updates)
|
||||||
|
return (json.dumps(result) + "\n").encode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def frame(tick=0, values=None, byte_count=None):
|
||||||
|
values = np.arange(4068, dtype="<f4") if values is None else np.asarray(values, dtype="<f4")
|
||||||
|
count = values.nbytes if byte_count is None else byte_count
|
||||||
|
return struct.pack("<qQ", tick, count) + values.tobytes()
|
||||||
|
|
||||||
|
|
||||||
|
class MemoryInput(io.BytesIO):
|
||||||
|
def close(self):
|
||||||
|
if not self.closed:
|
||||||
|
self.closed_data = self.getvalue()
|
||||||
|
super().close()
|
||||||
|
|
||||||
|
|
||||||
|
class FakeProcess:
|
||||||
|
"""The only use of OS descriptors is an anonymous read-only response pipe."""
|
||||||
|
def __init__(self, response, status=0, chunk_size=97):
|
||||||
|
read_fd, write_fd = os.pipe()
|
||||||
|
self.stdin = MemoryInput()
|
||||||
|
self.stdout = os.fdopen(read_fd, "rb", buffering=0)
|
||||||
|
self.status = status
|
||||||
|
self.terminated = False
|
||||||
|
|
||||||
|
def write_response():
|
||||||
|
try:
|
||||||
|
for begin in range(0, len(response), chunk_size):
|
||||||
|
view = memoryview(response[begin:begin + chunk_size])
|
||||||
|
while view:
|
||||||
|
view = view[os.write(write_fd, view):]
|
||||||
|
except (BrokenPipeError, OSError):
|
||||||
|
# Invalid-response tests deliberately close the reader early.
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
os.close(write_fd)
|
||||||
|
|
||||||
|
self.thread = threading.Thread(target=write_response, daemon=True)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def poll(self):
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
def wait(self, timeout=None):
|
||||||
|
return self.status
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
self.terminated = True
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
self.terminated = True
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if not self.stdin.closed:
|
||||||
|
self.stdin.close()
|
||||||
|
if not self.stdout.closed:
|
||||||
|
self.stdout.close()
|
||||||
|
self.thread.join(timeout=2)
|
||||||
|
|
||||||
|
|
||||||
|
class ProtocolTests(unittest.TestCase):
|
||||||
|
def create_worker(self, response, status=0):
|
||||||
|
process = FakeProcess(response, status=status)
|
||||||
|
self.addCleanup(process.close)
|
||||||
|
source_patch = mock.patch.object(ORACLE, "_digest", return_value="frozen-test-hash")
|
||||||
|
process_patch = mock.patch.object(ORACLE.subprocess, "Popen", return_value=process)
|
||||||
|
source_patch.start()
|
||||||
|
process_mock = process_patch.start()
|
||||||
|
self.addCleanup(source_patch.stop)
|
||||||
|
self.addCleanup(process_patch.stop)
|
||||||
|
worker = ORACLE._APLWorker(Path("science-python"), Path("legacy_apl_worker.py"), Path("bundle"), None, timeout=2)
|
||||||
|
self.addCleanup(worker.abort)
|
||||||
|
return worker, process, process_mock
|
||||||
|
|
||||||
|
def test_exact_handshake_frame_and_clean_eof(self):
|
||||||
|
worker, process, process_mock = self.create_worker(handshake() + frame())
|
||||||
|
globals_ = np.array([1, 40, 166699], dtype=np.int32)
|
||||||
|
drive, state, inhibition = worker.step(0, globals_)
|
||||||
|
values = np.arange(4068, dtype=np.float32)
|
||||||
|
np.testing.assert_array_equal(drive, values[:2])
|
||||||
|
np.testing.assert_array_equal(state, values[2:4])
|
||||||
|
np.testing.assert_array_equal(inhibition, values[4:])
|
||||||
|
request = process.stdin.getvalue()
|
||||||
|
self.assertEqual(struct.unpack("<qQ", request[:16]), (0, 3))
|
||||||
|
np.testing.assert_array_equal(np.frombuffer(request[16:], dtype="<i4"), globals_)
|
||||||
|
self.assertEqual(worker.finish(1), 0)
|
||||||
|
command = process_mock.call_args.args[0]
|
||||||
|
self.assertEqual(command, ["science-python", "-B", "legacy_apl_worker.py", "--bundle-dir", "bundle", "--dt-ms", "0.1"])
|
||||||
|
self.assertFalse(process_mock.call_args.kwargs["shell"])
|
||||||
|
|
||||||
|
def test_empty_spike_frame_still_advances_one_tick(self):
|
||||||
|
worker, process, _ = self.create_worker(handshake() + frame(values=np.zeros(4068, np.float32)))
|
||||||
|
arrays = worker.step(0, np.empty(0, np.int32))
|
||||||
|
self.assertTrue(all(np.all(value == 0) for value in arrays))
|
||||||
|
self.assertEqual(process.stdin.getvalue(), struct.pack("<qQ", 0, 0))
|
||||||
|
self.assertEqual(worker.finish(1), 0)
|
||||||
|
|
||||||
|
def test_two_consecutive_ticks(self):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame(0) + frame(1))
|
||||||
|
worker.step(0, np.array([4], np.int32))
|
||||||
|
worker.step(1, np.array([8, 10], np.int32))
|
||||||
|
self.assertEqual(worker.finish(2), 0)
|
||||||
|
|
||||||
|
def test_rejects_wrong_protocol_or_dimensions(self):
|
||||||
|
for update in ({"protocol": "other"}, {"ok": False}, {"n_neurons": 42},
|
||||||
|
{"n_kc": 3}, {"dt_ms": .2}, {"gain_f32_bits": "00000000"},
|
||||||
|
{"files_sha256": {}}):
|
||||||
|
with self.subTest(update=update):
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
self.create_worker(handshake(**update))
|
||||||
|
|
||||||
|
def test_rejects_wrong_tick_or_payload_length(self):
|
||||||
|
for response in (frame(tick=1), frame(byte_count=8)):
|
||||||
|
with self.subTest(response_header=response[:16]):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + response)
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
|
||||||
|
def test_rejects_truncated_response(self):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame()[:-1])
|
||||||
|
with self.assertRaises(EOFError):
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
|
||||||
|
def test_rejects_nonfinite_or_negative_apl_payload(self):
|
||||||
|
for bad_value in (np.nan, np.inf, -1):
|
||||||
|
with self.subTest(value=bad_value):
|
||||||
|
values = np.zeros(4068, np.float32)
|
||||||
|
values[-1] = bad_value
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame(values=values))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
|
||||||
|
def test_rejects_invalid_spike_dtype_order_and_range(self):
|
||||||
|
for values in (np.array([1], np.int64), np.array([2, 1], np.int32),
|
||||||
|
np.array([1, 1], np.int32), np.array([-1], np.int32),
|
||||||
|
np.array([166700], np.int32)):
|
||||||
|
with self.subTest(values=values):
|
||||||
|
worker, process, _ = self.create_worker(handshake() + frame())
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(0, values)
|
||||||
|
self.assertEqual(process.stdin.getvalue(), b"")
|
||||||
|
|
||||||
|
def test_rejects_skipped_request_tick(self):
|
||||||
|
worker, process, _ = self.create_worker(handshake() + frame())
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.step(1, np.empty(0, np.int32))
|
||||||
|
self.assertEqual(process.stdin.getvalue(), b"")
|
||||||
|
|
||||||
|
def test_rejects_failed_exit_and_trailing_stdout(self):
|
||||||
|
for suffix, status in ((b"", 7), (b"unexpected", 0)):
|
||||||
|
with self.subTest(status=status, suffix=suffix):
|
||||||
|
worker, _, _ = self.create_worker(handshake() + frame() + suffix, status=status)
|
||||||
|
worker.step(0, np.empty(0, np.int32))
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
worker.finish(1)
|
||||||
|
|
||||||
|
def test_pipe_reader_timeout(self):
|
||||||
|
read_fd, write_fd = os.pipe()
|
||||||
|
stream = os.fdopen(read_fd, "rb", buffering=0)
|
||||||
|
reader = ORACLE._PipeReader(stream, .05)
|
||||||
|
try:
|
||||||
|
with self.assertRaises(TimeoutError):
|
||||||
|
reader.read(1)
|
||||||
|
finally:
|
||||||
|
os.close(write_fd)
|
||||||
|
reader.thread.join(timeout=2)
|
||||||
|
stream.close()
|
||||||
|
self.assertFalse(reader.thread.is_alive())
|
||||||
|
|
||||||
|
|
||||||
|
class ArithmeticAndIdentityContractTests(unittest.TestCase):
|
||||||
|
def test_si_conversion_must_follow_float64_promotion(self):
|
||||||
|
h32 = np.array([.01, 1 / 7, 123.456], dtype=np.float32)
|
||||||
|
correct = h32.astype(np.float64) * np.float64(.001)
|
||||||
|
early_conversion = (h32 * np.float32(.001)).astype(np.float64)
|
||||||
|
self.assertFalse(np.array_equal(correct.view(np.uint64), early_conversion.view(np.uint64)))
|
||||||
|
for actual, original in zip(correct, h32):
|
||||||
|
self.assertEqual(actual.hex(), (float(original) * float(.001)).hex())
|
||||||
|
|
||||||
|
def test_declared_overlay_does_not_guard_refractory_targets(self):
|
||||||
|
before = np.array([0, -.002, .001], dtype=np.float64)
|
||||||
|
refractory = np.array([22, 21, 0], dtype=np.int32)
|
||||||
|
h32 = np.array([1, 2, 3], dtype=np.float32)
|
||||||
|
delta = h32.astype(np.float64) * np.float64(.001)
|
||||||
|
after = before - delta
|
||||||
|
self.assertTrue(np.all(after != before))
|
||||||
|
np.testing.assert_array_equal(refractory, [22, 21, 0])
|
||||||
|
self.assertEqual(after[0], -.001)
|
||||||
|
|
||||||
|
def test_af_queue_hash_keeps_original_noncontiguous_ids_and_rejections(self):
|
||||||
|
path = HERE.parent / "author-fullgraph-lab-v1" / "oracle_full.py"
|
||||||
|
self.assertEqual(hashlib.sha256(path.read_bytes()).hexdigest(), ORACLE.AF_SHA256)
|
||||||
|
af = load_no_cache(path, "phase4ag_protocol_af")
|
||||||
|
edges = np.array([81, 2, 500], dtype=np.int64)
|
||||||
|
accepted = np.array([1, 0, 1], dtype=np.uint8)
|
||||||
|
original_edges, original_mask = edges.copy(), accepted.copy()
|
||||||
|
result = af.queue_summary(18, edges, accepted, chunk_bytes=8)
|
||||||
|
packet = b"phase4af-queue-v1\0" + struct.pack("<qq", 18, 3) + edges.astype("<i8").tobytes() + accepted.tobytes()
|
||||||
|
self.assertEqual(result["joint_sha256"], hashlib.sha256(packet).hexdigest())
|
||||||
|
self.assertEqual((result["count"], result["accepted_count"]), (3, 2))
|
||||||
|
self.assertEqual(result, af.queue_summary(18, edges, accepted, chunk_bytes=8192))
|
||||||
|
np.testing.assert_array_equal(edges, original_edges)
|
||||||
|
np.testing.assert_array_equal(accepted, original_mask)
|
||||||
|
|
||||||
|
def test_empty_queue_hash_includes_tick(self):
|
||||||
|
af = load_no_cache(HERE.parent / "author-fullgraph-lab-v1" / "oracle_full.py", "phase4ag_empty_af")
|
||||||
|
first = af.queue_summary(0, np.empty(0, np.int64), np.empty(0, np.uint8))
|
||||||
|
second = af.queue_summary(1, np.empty(0, np.int64), np.empty(0, np.uint8))
|
||||||
|
self.assertEqual(first["ordered_edge_sha256"], hashlib.sha256(b"").hexdigest())
|
||||||
|
self.assertNotEqual(first["joint_sha256"], second["joint_sha256"])
|
||||||
|
|
||||||
|
def test_oracle_import_has_no_brian_or_torch_dependency(self):
|
||||||
|
before = set(sys.modules)
|
||||||
|
load_no_cache(HERE / "oracle_apl.py", "phase4ag_second_import")
|
||||||
|
added = set(sys.modules) - before
|
||||||
|
self.assertFalse(any(name == "brian2" or name.startswith("brian2.") or
|
||||||
|
name == "torch" or name.startswith("torch.") for name in added))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main(verbosity=2)
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
"""Regression for an execution-path error, unrelated to brain dynamics."""
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest import TestCase,main,mock,skipIf
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
from oracle_apl import _python_entry
|
||||||
|
|
||||||
|
|
||||||
|
class PythonEntryTests(TestCase):
|
||||||
|
@skipIf(os.name=='nt','Real POSIX interpreter symlink is validated on the task server')
|
||||||
|
def test_real_symlink_remains_invocation_path(self):
|
||||||
|
with tempfile.TemporaryDirectory(prefix='phase4ag-entry-') as folder:
|
||||||
|
path=Path(folder)/'python'
|
||||||
|
path.symlink_to(sys.executable)
|
||||||
|
self.assertEqual(_python_entry(path),path)
|
||||||
|
self.assertNotEqual(_python_entry(path),path.resolve())
|
||||||
|
|
||||||
|
@skipIf(os.name=='nt','POSIX dangling symlink test is validated on the task server')
|
||||||
|
def test_real_dangling_link_and_directory_rejected(self):
|
||||||
|
with tempfile.TemporaryDirectory(prefix='phase4ag-entry-') as folder:
|
||||||
|
path=Path(folder)/'python'
|
||||||
|
path.symlink_to(Path(folder)/'absent')
|
||||||
|
with self.assertRaises(ValueError):_python_entry(path)
|
||||||
|
with self.assertRaises(ValueError):_python_entry(Path(folder))
|
||||||
|
|
||||||
|
def test_preserves_declared_venv_path_without_resolving_symlink(self):
|
||||||
|
entry=Path.cwd()/'.fixture-venv/bin/python'
|
||||||
|
with mock.patch.object(Path,'resolve',side_effect=AssertionError('Must not resolve interpreter symlink')):
|
||||||
|
with mock.patch.object(Path,'is_file',return_value=True):
|
||||||
|
self.assertEqual(_python_entry(entry),entry)
|
||||||
|
|
||||||
|
def test_missing_python_entry_is_rejected(self):
|
||||||
|
with mock.patch.object(Path,'is_file',return_value=False):
|
||||||
|
with self.assertRaises(ValueError):_python_entry('/missing/python')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
@@ -0,0 +1,431 @@
|
|||||||
|
"""Independent extraction/replay of the frozen legacy APL component.
|
||||||
|
|
||||||
|
Only the initializer prefix before ``self.base`` and two original APL update
|
||||||
|
statements are executed. No old simulator is instantiated, no learning code is
|
||||||
|
executed, and no frozen artifact is written. The Torch replay is a component
|
||||||
|
oracle, not an independent CPU whole-brain closed-loop oracle.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import ast
|
||||||
|
import copy
|
||||||
|
from functools import lru_cache
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
from pathlib import Path
|
||||||
|
import struct
|
||||||
|
import types
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pyarrow.parquet as pq
|
||||||
|
import torch
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path('/data/digital-drosophila')
|
||||||
|
CANONICAL = ROOT/'datasets/male-cns-v1.0/processed/neuron-only'
|
||||||
|
SOURCE = ROOT/'models/male-cns-lif/deterministic-runtime-v2/phase4p_revalidate.py'
|
||||||
|
SOURCE_SHA256 = 'c7e693a2da70acdce4f53af5c2853e52e8333acc93f88a46a5e8083eac639346'
|
||||||
|
N, A, K = 166700, 2, 4064
|
||||||
|
BUNDLE_ARRAYS = {
|
||||||
|
'input_matrix': (np.float32, (A, N)), 'output_matrix': (np.float32, (A, K)),
|
||||||
|
'input_raw': (np.float32, (A, N)), 'output_raw': (np.float32, (A, K)),
|
||||||
|
'kc_globals': (np.int32, (K,)), 'apl_globals': (np.int32, (A,)),
|
||||||
|
'pn_globals': (np.int32, None), 'apl_out_ids': (np.int64, (5845,)),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def require(condition, message):
|
||||||
|
if not condition:
|
||||||
|
raise ValueError(message)
|
||||||
|
|
||||||
|
|
||||||
|
def digest(path):
|
||||||
|
h = hashlib.sha256()
|
||||||
|
with Path(path).open('rb') as source:
|
||||||
|
for block in iter(lambda: source.read(8 << 20), b''):
|
||||||
|
h.update(block)
|
||||||
|
return h.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def array_hash(value):
|
||||||
|
return hashlib.sha256(np.ascontiguousarray(value).tobytes()).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def bit_equal(a, b):
|
||||||
|
a, b = np.asarray(a), np.asarray(b)
|
||||||
|
return bool(a.dtype == b.dtype and a.shape == b.shape and
|
||||||
|
np.array_equal(np.ascontiguousarray(a).view(np.uint8),
|
||||||
|
np.ascontiguousarray(b).view(np.uint8)))
|
||||||
|
|
||||||
|
|
||||||
|
def save(path, value):
|
||||||
|
path = Path(path)
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
with path.open('x', encoding='utf-8') as target:
|
||||||
|
json.dump(value, target, indent=2, sort_keys=True, allow_nan=False)
|
||||||
|
target.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
class ReadOnlyNamespace:
|
||||||
|
"""The extracted prefix can read rt, but cannot mutate or add rt fields."""
|
||||||
|
def __init__(self, **values):
|
||||||
|
object.__setattr__(self, '_values', types.MappingProxyType(values))
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return self._values[name]
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
raise AttributeError('Read-only canonical runtime view')
|
||||||
|
|
||||||
|
|
||||||
|
def _code(nodes, filename):
|
||||||
|
module = ast.Module(body=copy.deepcopy(nodes), type_ignores=[])
|
||||||
|
return compile(ast.fix_missing_locations(module), str(filename), 'exec')
|
||||||
|
|
||||||
|
|
||||||
|
def _self_attribute(target, field):
|
||||||
|
return isinstance(target, ast.Attribute) and isinstance(target.value, ast.Name) and \
|
||||||
|
target.value.id == 'self' and target.attr == field
|
||||||
|
|
||||||
|
|
||||||
|
def extract_statements():
|
||||||
|
data = SOURCE.read_bytes()
|
||||||
|
require(hashlib.sha256(data).hexdigest() == SOURCE_SHA256, 'Frozen legacy source SHA-256 mismatch')
|
||||||
|
text = data.decode('utf-8')
|
||||||
|
tree = ast.parse(text, filename=str(SOURCE))
|
||||||
|
classes = [node for node in tree.body if isinstance(node, ast.ClassDef) and node.name == 'DeterministicAPLSim']
|
||||||
|
require(len(classes) == 1, 'Expected exactly one frozen DeterministicAPLSim')
|
||||||
|
methods = {node.name: node for node in classes[0].body if isinstance(node, ast.FunctionDef)}
|
||||||
|
init, run = methods['__init__'], methods['run']
|
||||||
|
cuts = [i for i, node in enumerate(init.body) if isinstance(node, ast.Assign) and
|
||||||
|
any(_self_attribute(target, 'base') for target in node.targets)]
|
||||||
|
require(len(cuts) == 1 and cuts[0] > 0, 'Missing/ambiguous self.base cutoff')
|
||||||
|
prefix = init.body[:cuts[0]]
|
||||||
|
# Executing no import or file-writing call is allowed in the extracted prefix.
|
||||||
|
require(not any(isinstance(node, (ast.Import, ast.ImportFrom, ast.With, ast.AsyncWith))
|
||||||
|
for stmt in prefix for node in ast.walk(stmt)), 'Unexpected side-effect construct in initializer prefix')
|
||||||
|
expressions = [node for node in ast.walk(run) if isinstance(node, ast.Expr) and
|
||||||
|
isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Attribute) and
|
||||||
|
node.value.func.attr == 'add_' and isinstance(node.value.func.value, ast.Call) and
|
||||||
|
isinstance(node.value.func.value.func, ast.Attribute) and
|
||||||
|
isinstance(node.value.func.value.func.value, ast.Name) and
|
||||||
|
node.value.func.value.func.value.id == 'apl_state' and node.value.func.value.func.attr == 'mul_']
|
||||||
|
inhibition = [node for node in ast.walk(run) if isinstance(node, ast.Assign) and
|
||||||
|
any(isinstance(target, ast.Name) and target.id == 'inhibition' for target in node.targets)]
|
||||||
|
decay = [node for node in ast.walk(run) if isinstance(node, ast.Assign) and
|
||||||
|
any(isinstance(target, ast.Name) and target.id == 'apl_decay' for target in node.targets)]
|
||||||
|
require(len(expressions) == len(inhibition) == len(decay) == 1, 'Ambiguous frozen APL operator extraction')
|
||||||
|
require(expressions[0].lineno < inhibition[0].lineno, 'Unexpected frozen APL update order')
|
||||||
|
rhs = inhibition[0].value
|
||||||
|
require(isinstance(rhs, ast.BinOp) and isinstance(rhs.op, ast.Mult), 'Unexpected inhibition gain expression')
|
||||||
|
gain_expression = ast.Expression(copy.deepcopy(rhs.right))
|
||||||
|
provenance = {'source': str(SOURCE), 'sha256': SOURCE_SHA256,
|
||||||
|
'initializer_line_start': prefix[0].lineno, 'initializer_line_end': prefix[-1].end_lineno,
|
||||||
|
'excluded_self_base_line': init.body[cuts[0]].lineno,
|
||||||
|
'decay_line': decay[0].lineno, 'state_update_line': expressions[0].lineno,
|
||||||
|
'inhibition_line': inhibition[0].lineno,
|
||||||
|
'initializer_source': '\n'.join(ast.get_source_segment(text, node) for node in prefix),
|
||||||
|
'decay_source': ast.get_source_segment(text, decay[0]),
|
||||||
|
'state_update_source': ast.get_source_segment(text, expressions[0]),
|
||||||
|
'inhibition_source': ast.get_source_segment(text, inhibition[0]),
|
||||||
|
'learning_initializer_suffix_executed': False, 'original_run_loop_executed': False}
|
||||||
|
return (_code(prefix, SOURCE), _code(decay, SOURCE),
|
||||||
|
_code([expressions[0], inhibition[0]], SOURCE),
|
||||||
|
compile(ast.fix_missing_locations(gain_expression), str(SOURCE), 'eval'), provenance)
|
||||||
|
|
||||||
|
|
||||||
|
def _canonical_files():
|
||||||
|
return {name: CANONICAL/path for name, path in {
|
||||||
|
'metadata': 'neuron-index/unified-metadata.parquet',
|
||||||
|
'indptr': 'gpu/csr-indptr.int64.npy', 'indices': 'gpu/csr-indices.int32.npy',
|
||||||
|
'raw': 'gpu/csr-weights.int64.npy'}.items()}
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache(maxsize=2)
|
||||||
|
def reconstruct(canonical_hashes, device_name):
|
||||||
|
"""Cache only reconstructions tied to exact canonical bytes and source hash."""
|
||||||
|
files = _canonical_files()
|
||||||
|
require(dict(canonical_hashes) == {name: digest(path) for name, path in files.items()},
|
||||||
|
'Canonical bytes changed before matrix reconstruction')
|
||||||
|
arrays = {name: np.load(files[name], mmap_mode='r', allow_pickle=False)
|
||||||
|
for name in ('indptr', 'indices', 'raw')}
|
||||||
|
require(arrays['indptr'].dtype == np.int64 and arrays['indices'].dtype == np.int32 and
|
||||||
|
arrays['raw'].dtype == np.int64, 'Canonical CSR dtypes changed')
|
||||||
|
require(arrays['indptr'].shape == (N + 1,) and arrays['indptr'][-1] == 25582938 and
|
||||||
|
arrays['indices'].shape == arrays['raw'].shape == (25582938,), 'Canonical graph shape changed')
|
||||||
|
require(int(arrays['raw'].sum()) == 124177617 and bool(np.all(arrays['raw'] > 0)), 'Canonical raw weights changed')
|
||||||
|
table = pq.read_table(files['metadata'])
|
||||||
|
require(table.num_rows == N, 'Canonical metadata count changed')
|
||||||
|
rt = ReadOnlyNamespace(n=N, dt=.1, device=torch.device(device_name), table=table,
|
||||||
|
indptr_np=arrays['indptr'], indices_np=arrays['indices'], raw_np=arrays['raw'])
|
||||||
|
view = types.SimpleNamespace()
|
||||||
|
init_code, decay_code, update_code, gain_code, provenance = extract_statements()
|
||||||
|
scope = {'self': view, 'rt': rt, 'np': np, 'torch': torch}
|
||||||
|
exec(init_code, scope)
|
||||||
|
require(not hasattr(view, 'base') and not hasattr(view, 'identity'), 'Initializer crossed the learning cutoff')
|
||||||
|
expected = {'input_matrix': view.input_gpu.detach().cpu().numpy().copy(),
|
||||||
|
'output_matrix': view.output_gpu.detach().cpu().numpy().copy(),
|
||||||
|
'input_raw': scope['input_matrix'], 'output_raw': scope['output_matrix'],
|
||||||
|
'kc_globals': view.kc, 'apl_globals': view.apl, 'pn_globals': view.pn,
|
||||||
|
'apl_out_ids': view.apl_out_ids}
|
||||||
|
for value in expected.values():
|
||||||
|
value.flags.writeable = False
|
||||||
|
return view, expected, provenance, (decay_code, update_code, gain_code)
|
||||||
|
|
||||||
|
|
||||||
|
class TorchObservationProxy:
|
||||||
|
"""Observe the result of the actual extracted torch.mv call unchanged."""
|
||||||
|
def __init__(self):
|
||||||
|
self.drive = None
|
||||||
|
self.calls = 0
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return getattr(torch, name)
|
||||||
|
|
||||||
|
def mv(self, *args, **kwargs):
|
||||||
|
value = torch.mv(*args, **kwargs)
|
||||||
|
self.drive = value
|
||||||
|
self.calls += 1
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _up(value):
|
||||||
|
return np.nextafter(np.asarray(value, dtype=np.float64), np.inf)
|
||||||
|
|
||||||
|
|
||||||
|
def _add(a, b):
|
||||||
|
return _up(np.asarray(a, dtype=np.float64) + np.asarray(b, dtype=np.float64))
|
||||||
|
|
||||||
|
|
||||||
|
def _mul(a, b):
|
||||||
|
return _up(np.asarray(a, dtype=np.float64) * np.asarray(b, dtype=np.float64))
|
||||||
|
|
||||||
|
|
||||||
|
def _gamma(count, unit_roundoff):
|
||||||
|
require(count * unit_roundoff < 1, 'Gamma bound is undefined')
|
||||||
|
# Outward rounding on the division; the denominator is rounded downward.
|
||||||
|
numerator = _mul(count, unit_roundoff)
|
||||||
|
denominator = np.nextafter(1.0 - numerator, -np.inf)
|
||||||
|
return _up(numerator / denominator)
|
||||||
|
|
||||||
|
|
||||||
|
def _positive_dot_upper(state, matrix):
|
||||||
|
result = np.zeros(matrix.shape[1], np.float64)
|
||||||
|
for index in range(len(state)):
|
||||||
|
result = _add(result, _mul(state[index], matrix[index]))
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _normal_or_zero(value, tiny):
|
||||||
|
value = np.asarray(value)
|
||||||
|
return bool(np.all((value == 0) | (value >= tiny)))
|
||||||
|
|
||||||
|
|
||||||
|
def _new_metric():
|
||||||
|
return {'max_abs_error': 0.0, 'sum_abs_error': 0.0, 'elements': 0,
|
||||||
|
'max_relative_error_nonzero_reference': 0.0, 'zero_reference_nonzero_actual': 0,
|
||||||
|
'max_error_bound': 0.0, 'max_bound_utilization': 0.0, 'bound_violations': 0}
|
||||||
|
|
||||||
|
|
||||||
|
def _accumulate(metric, actual, reference, bound):
|
||||||
|
error = np.abs(np.asarray(actual, np.float64) - reference)
|
||||||
|
error_upper = np.where(error == 0, 0.0, _up(error))
|
||||||
|
nonzero = reference != 0
|
||||||
|
ratio = np.divide(error, np.abs(reference), out=np.zeros_like(error), where=nonzero)
|
||||||
|
usage = np.divide(error_upper, bound, out=np.zeros_like(error), where=bound > 0)
|
||||||
|
metric['max_abs_error'] = max(metric['max_abs_error'], float(error.max(initial=0)))
|
||||||
|
metric['sum_abs_error'] += float(error.sum(dtype=np.float64))
|
||||||
|
metric['elements'] += error.size
|
||||||
|
metric['max_relative_error_nonzero_reference'] = max(metric['max_relative_error_nonzero_reference'], float(ratio.max(initial=0)))
|
||||||
|
metric['zero_reference_nonzero_actual'] += int(np.count_nonzero((~nonzero) & (error != 0)))
|
||||||
|
metric['max_error_bound'] = max(metric['max_error_bound'], float(np.max(bound, initial=0)))
|
||||||
|
metric['max_bound_utilization'] = max(metric['max_bound_utilization'], float(usage.max(initial=0)))
|
||||||
|
metric['bound_violations'] += int(np.count_nonzero(error_upper > bound))
|
||||||
|
|
||||||
|
|
||||||
|
def validate(gpu_case_dir, bundle_dir, out_json):
|
||||||
|
"""Validate one completed fixture; write one exclusive pure-JSON audit."""
|
||||||
|
gpu_case_dir, bundle_dir, out_json = Path(gpu_case_dir), Path(bundle_dir), Path(out_json)
|
||||||
|
require(not out_json.exists(), 'Refusing to overwrite an existing component audit')
|
||||||
|
report = {'pass_all': False, 'scope': 'Frozen APL component extraction and recorded-spike replay only',
|
||||||
|
'independent_cpu_closed_loop_oracle': False, 'brain_or_learning_parameters_changed': False,
|
||||||
|
'candidate_function_called': False, 'gpu_case_dir': str(gpu_case_dir), 'bundle_dir': str(bundle_dir)}
|
||||||
|
try:
|
||||||
|
require(digest(SOURCE) == SOURCE_SHA256, 'Frozen source changed before component validation')
|
||||||
|
require(torch.cuda.is_available() and torch.cuda.device_count() == 1 and
|
||||||
|
'4090' in torch.cuda.get_device_name(), 'Require the one declared RTX4090')
|
||||||
|
environment = {'torch': str(torch.__version__), 'numpy': np.__version__,
|
||||||
|
'gpu': torch.cuda.get_device_name(), 'cuda': torch.version.cuda,
|
||||||
|
'cuda_matmul_allow_tf32': torch.backends.cuda.matmul.allow_tf32,
|
||||||
|
'float32_matmul_precision': torch.get_float32_matmul_precision(),
|
||||||
|
'deterministic_algorithms': torch.are_deterministic_algorithms_enabled(),
|
||||||
|
'precision_flags_changed': False}
|
||||||
|
report['environment'] = environment
|
||||||
|
canonical_hashes = tuple(sorted((name, digest(path)) for name, path in _canonical_files().items()))
|
||||||
|
view, reconstructed, provenance, code = reconstruct(canonical_hashes, 'cuda:0')
|
||||||
|
bundle = {}
|
||||||
|
matrix_checks = {}
|
||||||
|
for name, (dtype, shape) in BUNDLE_ARRAYS.items():
|
||||||
|
value = np.load(bundle_dir/(name+'.npy'), mmap_mode='r', allow_pickle=False)
|
||||||
|
require(value.dtype == dtype and value.ndim == len(shape or (0,)) and
|
||||||
|
(shape is None or value.shape == shape), 'Bundle schema mismatch: '+name)
|
||||||
|
bundle[name] = value
|
||||||
|
matrix_checks[name] = bit_equal(value, reconstructed[name])
|
||||||
|
scales = json.loads((bundle_dir/'scales.json').read_text())
|
||||||
|
for name in ('input_scale', 'output_scale'):
|
||||||
|
matrix_checks[name] = struct.pack('<d', float(scales[name])) == struct.pack('<d', float(getattr(view, name)))
|
||||||
|
report['matrix_checks'] = matrix_checks
|
||||||
|
report['extracted_source'] = provenance
|
||||||
|
report['canonical_sha256'] = dict(canonical_hashes)
|
||||||
|
report['bundle_sha256'] = {name+'.npy': digest(bundle_dir/(name+'.npy')) for name in BUNDLE_ARRAYS}
|
||||||
|
report['bundle_sha256']['scales.json'] = digest(bundle_dir/'scales.json')
|
||||||
|
report['reconstructed_array_sha256'] = {name: array_hash(value) for name, value in reconstructed.items()}
|
||||||
|
bundle_provenance = json.loads((bundle_dir/'provenance.json').read_text())
|
||||||
|
require(Path(bundle_provenance['canonical_root']).resolve() == CANONICAL.resolve(),
|
||||||
|
'Bundle provenance names another canonical dataset')
|
||||||
|
report['bundle_sha256']['provenance.json'] = digest(bundle_dir/'provenance.json')
|
||||||
|
require(all(matrix_checks.values()), 'Bundle differs from the actual frozen initializer prefix')
|
||||||
|
|
||||||
|
traces = {name: np.load(gpu_case_dir/('apl-'+name+'.float32.npy'), mmap_mode='r', allow_pickle=False)
|
||||||
|
for name in ('drive', 'state', 'inhibition')}
|
||||||
|
steps = len(traces['state'])
|
||||||
|
require(steps > 0, 'Empty APL trajectory cannot pass')
|
||||||
|
for name, width in (('drive', A), ('state', A), ('inhibition', K)):
|
||||||
|
require(traces[name].dtype == np.float32 and traces[name].shape == (steps, width) and
|
||||||
|
bool(np.isfinite(traces[name]).all()) and bool(np.all(traces[name] >= 0)), 'Invalid APL trace: '+name)
|
||||||
|
summary = json.loads((gpu_case_dir/'summary.json').read_text())
|
||||||
|
require(summary.get('complete') is True and summary.get('pass_all') is True and
|
||||||
|
summary.get('steps') == steps and summary.get('completed_ticks') == steps,
|
||||||
|
'GPU fixture did not complete its internal execution checks')
|
||||||
|
with np.load(gpu_case_dir/'state.npz', allow_pickle=False) as archive:
|
||||||
|
event_step, event_node = archive['step'].copy(), archive['neuron_idx'].copy()
|
||||||
|
require(event_step.dtype == event_node.dtype == np.int32 and event_step.ndim == 1 and
|
||||||
|
event_step.shape == event_node.shape, 'Invalid sparse actual spike event schema')
|
||||||
|
require(bool(np.all((event_step >= 0) & (event_step < steps))) and
|
||||||
|
bool(np.all((event_node >= 0) & (event_node < N))), 'Sparse event outside its clock/identity range')
|
||||||
|
require(np.array_equal(np.lexsort((event_node, event_step)), np.arange(len(event_step))), 'Actual events not sorted')
|
||||||
|
keys = event_step.astype(np.int64)*N + event_node
|
||||||
|
require(len(keys) < 2 or bool(np.all(np.diff(keys) > 0)), 'Duplicate actual spikes')
|
||||||
|
boundaries = np.searchsorted(event_step, np.arange(steps + 1))
|
||||||
|
|
||||||
|
proxy = TorchObservationProxy()
|
||||||
|
# Reconstructed original matrices are already on the original GPU/dtype.
|
||||||
|
replay_rt = types.SimpleNamespace(spike_u8=torch.zeros(N, dtype=torch.uint8, device=view.device))
|
||||||
|
shadow = types.SimpleNamespace(input_gpu=view.input_gpu, output_gpu=view.output_gpu, rt=replay_rt, dt=.1)
|
||||||
|
scope = {'self': shadow, 'np': np, 'math': math, 'torch': proxy,
|
||||||
|
'apl_state': torch.zeros(A, dtype=torch.float32, device=view.device)}
|
||||||
|
decay_code, update_code, gain_code = code
|
||||||
|
exec(decay_code, scope)
|
||||||
|
decay32 = np.float32(scope['apl_decay'])
|
||||||
|
gain32 = np.float32(eval(gain_code, {'np': np}))
|
||||||
|
require(0 < decay32 < 1 and gain32 > 0, 'Invalid extracted positive APL constants')
|
||||||
|
exact = {name: True for name in traces}
|
||||||
|
first_difference = None
|
||||||
|
I64 = np.asarray(bundle['input_matrix'], np.float64)
|
||||||
|
O64 = np.asarray(bundle['output_matrix'], np.float64)
|
||||||
|
require(bool(np.all(I64 >= 0)) and bool(np.all(O64 >= 0)), 'Positive-sum theory requires nonnegative matrices')
|
||||||
|
d, q = float(decay32), float(gain32)
|
||||||
|
u32, u64 = 2.0**-24, 2.0**-53
|
||||||
|
gd32, gd64 = _gamma(N-1, u32), _gamma(N-1, u64)
|
||||||
|
g232, g264 = _gamma(2, u32), _gamma(2, u64)
|
||||||
|
gh32, gh64 = _gamma(2*A+1, u32), _gamma(2*A+1, u64)
|
||||||
|
state64 = np.zeros(A, np.float64)
|
||||||
|
e32 = np.zeros(A, np.float64)
|
||||||
|
e64 = np.zeros(A, np.float64)
|
||||||
|
previous32 = np.zeros(A, np.float64)
|
||||||
|
statistics = {name: _new_metric() for name in traces}
|
||||||
|
normal_arithmetic = _normal_or_zero(I64, np.finfo(np.float32).tiny) and _normal_or_zero(O64, np.finfo(np.float32).tiny)
|
||||||
|
max_active_terms = 0
|
||||||
|
with torch.no_grad():
|
||||||
|
for tick in range(steps):
|
||||||
|
fired = event_node[boundaries[tick]:boundaries[tick+1]]
|
||||||
|
replay_rt.spike_u8.zero_()
|
||||||
|
if len(fired):
|
||||||
|
replay_rt.spike_u8[torch.as_tensor(fired.astype(np.int64), device=view.device)] = 1
|
||||||
|
before_calls = proxy.calls
|
||||||
|
exec(update_code, scope)
|
||||||
|
require(proxy.calls == before_calls + 1, 'Original update did not issue exactly one mv')
|
||||||
|
actual = {'drive': proxy.drive.detach().cpu().numpy(),
|
||||||
|
'state': scope['apl_state'].detach().cpu().numpy(),
|
||||||
|
'inhibition': scope['inhibition'].detach().cpu().numpy()}
|
||||||
|
for name in traces:
|
||||||
|
same = bit_equal(actual[name], traces[name][tick])
|
||||||
|
exact[name] &= same
|
||||||
|
if not same and first_difference is None:
|
||||||
|
first_difference = {'tick': tick, 'field': name,
|
||||||
|
'max_abs_error': float(np.max(np.abs(actual[name].astype(np.float64)-traces[name][tick])))}
|
||||||
|
# Float64 reference is measurement only and never feeds either brain.
|
||||||
|
selected = I64[:, fired]
|
||||||
|
drive64 = selected.sum(axis=1, dtype=np.float64)
|
||||||
|
max_active_terms = max(max_active_terms, int(np.count_nonzero(selected, axis=1).max(initial=0)))
|
||||||
|
Dupper = _up(drive64 / np.nextafter(1.0-gd64, -np.inf))
|
||||||
|
drive_bound = _add(_mul(gd32, Dupper), _mul(gd64, Dupper))
|
||||||
|
state32 = traces['state'][tick].astype(np.float64)
|
||||||
|
normal_arithmetic &= _normal_or_zero(d*previous32, np.finfo(np.float32).tiny)
|
||||||
|
normal_arithmetic &= _normal_or_zero(O64*state32[:, None], np.finfo(np.float32).tiny)
|
||||||
|
e32 = _add(_mul(d, e32), _add(_mul(g232, _add(_mul(d, previous32), Dupper)),
|
||||||
|
_mul(1.0+u32, _mul(gd32, Dupper))))
|
||||||
|
e64 = _add(_mul(d, e64), _add(_mul(g264, _add(_mul(d, state64), Dupper)),
|
||||||
|
_mul(1.0+u64, _mul(gd64, Dupper))))
|
||||||
|
state64 = d*state64 + drive64
|
||||||
|
inhibition64 = np.matmul(state64, O64)*q
|
||||||
|
h32bound = _add(_mul(q, _positive_dot_upper(e32, O64)),
|
||||||
|
_mul(gh32, _mul(q, _positive_dot_upper(state32, O64))))
|
||||||
|
h64bound = _add(_mul(q, _positive_dot_upper(e64, O64)),
|
||||||
|
_mul(gh64, _mul(q, _positive_dot_upper(state64, O64))))
|
||||||
|
normal_arithmetic &= _normal_or_zero(q*np.matmul(state32, O64), np.finfo(np.float32).tiny)
|
||||||
|
_accumulate(statistics['drive'], traces['drive'][tick], drive64, drive_bound)
|
||||||
|
_accumulate(statistics['state'], traces['state'][tick], state64, _add(e32, e64))
|
||||||
|
_accumulate(statistics['inhibition'], traces['inhibition'][tick], inhibition64, _add(h32bound, h64bound))
|
||||||
|
previous32 = state32
|
||||||
|
for metric in statistics.values():
|
||||||
|
metric['mean_abs_error'] = metric.pop('sum_abs_error') / metric['elements']
|
||||||
|
theory_applicable = bool(normal_arithmetic and not environment['cuda_matmul_allow_tf32'] and
|
||||||
|
environment['float32_matmul_precision'] == 'highest')
|
||||||
|
report.update(steps=steps, actual_spike_events=len(event_step),
|
||||||
|
ast_replay_bitwise_exact=exact, first_ast_difference=first_difference,
|
||||||
|
value_units={'drive': 'legacy normalized-contact spike drive',
|
||||||
|
'state': 'legacy normalized-drive accumulator', 'inhibition': 'legacy mV'},
|
||||||
|
decay_f32_bits=f'{int(decay32.view(np.uint32)):08x}', gain_f32_bits=f'{int(gain32.view(np.uint32)):08x}',
|
||||||
|
float64_measurement=statistics,
|
||||||
|
theoretical_bound={'applicable': theory_applicable, 'normal_or_zero_arithmetic': bool(normal_arithmetic),
|
||||||
|
'gamma_definition': 'gamma_n=(n*u)/(1-n*u), upward-rounded; u32=2^-24,u64=2^-53',
|
||||||
|
'drive_n': N-1, 'max_observed_nonzero_drive_terms': max_active_terms,
|
||||||
|
'gamma_drive_f32': float(gd32), 'gamma_drive_f64': float(gd64),
|
||||||
|
'state_recurrence': 'E_p[t] <= d*E_p[t-1] + gamma_2,p*(d*abs(s_p[t-1])+D_upper) + (1+u_p)*gamma_(N-1),p*D_upper',
|
||||||
|
'output_bound': 'q*sum(B*E_p) + gamma_(2*A+1),p*q*sum(B*abs(s_p)); compare with E32+E64',
|
||||||
|
'assumptions': 'nonnegative f32 matrices, spikes exactly 0/1, fixed stored f32 decay/gain, normal finite RN binary32/64 operations; no reduced-precision matmul',
|
||||||
|
'bound_arithmetic': 'Each positive bound operation is rounded toward +infinity via nextafter; denominator toward -infinity',
|
||||||
|
'tolerance_fitted_to_observed_error': False,
|
||||||
|
'f64_values_used_to_drive_brain': False,
|
||||||
|
'no_cpu_gpu_bitwise_expectation_for_f64_measurement': True},
|
||||||
|
input_sha256={name: digest(gpu_case_dir/name) for name in
|
||||||
|
('state.npz', 'summary.json', 'apl-drive.float32.npy', 'apl-state.float32.npy', 'apl-inhibition.float32.npy')})
|
||||||
|
report['pass_all'] = bool(all(matrix_checks.values()) and all(exact.values()) and theory_applicable and
|
||||||
|
all(value['bound_violations'] == 0 for value in statistics.values()))
|
||||||
|
report['limitations'] = [
|
||||||
|
'AST shadow and candidate use the same original Torch/CUDA primitives; this validates preserved component semantics, not an independent CPU whole-brain oracle.',
|
||||||
|
'Float64 is a non-feedback mathematical measurement with explicit gamma error bounds, not replacement APL dynamics.',
|
||||||
|
'Replay uses the recorded actual spike train; it does not establish equivalence for untested closed-loop inputs.',
|
||||||
|
'The N-1 positive-sum bound is deliberately conservative; passing it does not prove physiological validity or learning.']
|
||||||
|
save(out_json, report)
|
||||||
|
return report
|
||||||
|
except Exception as error:
|
||||||
|
report['error'] = {'type': type(error).__name__, 'message': str(error)}
|
||||||
|
if not out_json.exists():
|
||||||
|
save(out_json, report)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('gpu_case_dir', type=Path)
|
||||||
|
parser.add_argument('bundle_dir', type=Path)
|
||||||
|
parser.add_argument('out_json', type=Path)
|
||||||
|
args = parser.parse_args()
|
||||||
|
result = validate(args.gpu_case_dir, args.bundle_dir, args.out_json)
|
||||||
|
print(json.dumps({'pass_all': result['pass_all'], 'steps': result['steps']}), flush=True)
|
||||||
|
if not result['pass_all']:
|
||||||
|
raise SystemExit(1)
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
"""Run old reference unchanged, writing only new experiment output."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
import yaml
|
||||||
|
from context import ROOT,EXP,CFG,save,check
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
check();assert not (EXP/'regression/frozen-five.json').exists()
|
||||||
|
rtpath=ROOT/'models/male-cns-lif/deterministic-runtime-v2';pc=yaml.safe_load((rtpath/'phase4p.yaml').read_text())
|
||||||
|
os.environ['CUDA_VISIBLE_DEVICES']=CFG['gpu_uuid'];os.environ['CUDA_HOME']='/usr/local/cuda'
|
||||||
|
os.environ['PATH']=str(ROOT/'models/male-cns-lif/.venv/bin')+':/usr/local/cuda/bin:'+os.environ['PATH']
|
||||||
|
os.environ['MAX_JOBS']='2';os.environ['TORCH_CUDA_ARCH_LIST']='8.9'
|
||||||
|
sys.path.insert(0,str(ROOT/'models/male-cns-lif/terminal-scope-diagnostic-v1'))
|
||||||
|
from diagnostic import queues
|
||||||
|
queues();sys.path.insert(0,str(ROOT/'models/male-cns-lif'));sys.path.insert(0,str(rtpath))
|
||||||
|
import torch,phase4p
|
||||||
|
assert torch.cuda.mem_get_info()[0]>2*1024**3
|
||||||
|
torch.cuda.reset_peak_memory_stats();t0=time.perf_counter();rt=phase4p.CanonicalRuntime(pc,rtpath,EXP);rows=[]
|
||||||
|
for spec in pc['reference_trials']:
|
||||||
|
queues();base=ROOT/'experiments/phase4p-deterministic-runtime/phase4c-v2/reference'/spec['name']
|
||||||
|
ev=pd.read_parquet(base/'spike-events.parquet')
|
||||||
|
ref=dict(step=ev.step.to_numpy(),neuron_idx=ev.neuron_idx.to_numpy(),counts=np.load(base/'per-neuron-spike-counts.int32.npy'),v=np.load(base/'final-voltage.float32.npy'),g=np.load(base/'final-g.float32.npy'))
|
||||||
|
result=rt.run(np.flatnonzero(rt.pops[spec['population']]),spec['rate_hz'],spec['seed'],spec['duration_ms'])
|
||||||
|
row=dict(trial=spec['name'],exact={k:bool(np.array_equal(v,result[k])) for k,v in ref.items()},wall_seconds=result['metrics']['wall_seconds'])
|
||||||
|
rows.append(row);print(row,flush=True)
|
||||||
|
save(EXP/'regression/frozen-five.json',dict(pass_all=all(all(r['exact'].values()) for r in rows),trials=rows,
|
||||||
|
wall_seconds=time.perf_counter()-t0,peak_allocated_vram=int(torch.cuda.max_memory_allocated()),oracle='old frozen deterministic-v2 only'))
|
||||||
|
assert all(all(r['exact'].values()) for r in rows)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=='__main__':main()
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
|||||||
|
# Phase 4AG: author LIF + unchanged legacy graded APL
|
||||||
|
|
||||||
|
Status: `FAIL-FIXED-CAL-REPRESENTATION`.
|
||||||
|
|
||||||
|
Numerical closed-loop gate: True; original complete fixed six-CAL gate: False.
|
||||||
|
The independent Brian LIF and candidate use independent state but share the APL arithmetic component. Original frozen APL AST replay and a float64 error audit are separately recorded.
|
||||||
|
Author LIF uses float64; APL retains float32, tau20ms/gain0.01/normalization1, full original matrices and order. No learning/parameter search.
|
||||||
|
The explicitly hypothesized unconditional end-APL write includes refractory KC. Original fast APL mask leaves1,212 non-KC edges unreplaced; this scope limitation was not silently fixed.
|
||||||
|
Old checksums and five frozen reference trials: True.
|
||||||
|
Successfully compared cases: [{'case': 'apl_only', 'pass_all': True}, {'case': 'arrival_collision', 'pass_all': True}, {'case': 'cal-matched_energy-00-s51101', 'pass_all': True}, {'case': 'cal-physiological-00-s51101', 'pass_all': True}, {'case': 'high_fanin', 'pass_all': True}, {'case': 'kc_ref_boundary', 'pass_all': True}, {'case': 'natural_request', 'pass_all': True}, {'case': 'pn_pulse', 'pass_all': True}, {'case': 'two_sources', 'pass_all': True}, {'case': 'zero', 'pass_all': True}].
|
||||||
|
Detailed CAL, exact comparisons, component errors, event/request traces and execution exceptions are linked from audit/final-status.json.
|
||||||
|
Wall/VRAM here include per-tick CPU synchronization, IPC and hashes. They are diagnostic costs, not runtime-performance benchmarks.
|
||||||
|
No heldout dynamic outputs, formal A/B, learning, game, reward, decoder or new candidate.
|
||||||
|
Next gate: Audit first failure in this explicitly declared hypothesis; no gain search, no heldout tuning, no conditioning
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"canonical_root": "/data/digital-drosophila/datasets/male-cns-v1.0/processed/neuron-only",
|
||||||
|
"source": "/data/digital-drosophila/models/male-cns-lif/deterministic-runtime-v2/phase4p_revalidate.py",
|
||||||
|
"source_sha256": "c7e693a2da70acdce4f53af5c2853e52e8333acc93f88a46a5e8083eac639346",
|
||||||
|
"parameters": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"lock_file": "/data/digital-drosophila/experiments/phase4j-mb-physiology-repair/calibration/locked-parameters.json",
|
||||||
|
"lock_sha256": "1894cc4b4082ba9b2d069edf87c5eccb75292aa11947ad9c48acf661037ff3e7",
|
||||||
|
"full_dimensions": [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
166700
|
||||||
|
],
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
4064
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"APL": 2,
|
||||||
|
"KC": 4064,
|
||||||
|
"ALPN": 686,
|
||||||
|
"APL_fast_edges": 5845,
|
||||||
|
"APL_nonKC_edges": 1212,
|
||||||
|
"APL_nonKC_contacts": 13712,
|
||||||
|
"normalization_recomputed_in_original_order": true,
|
||||||
|
"raw_files_modified": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"input_scale": 49.65891647338867,
|
||||||
|
"output_scale": 42.34836959838867
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"pass_all": false,
|
||||||
|
"scope": "Complete original six-CAL representation gate, not heldout or learning",
|
||||||
|
"summary": "calibration/summary.json"
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 47,
|
||||||
|
"accepted_requests": 2,
|
||||||
|
"active_neurons": 2,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 50,
|
||||||
|
"case": "apl_only",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/apl_only",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/apl_only/arrays.npz": "c256234eec74752513c95d961233e7c1a7b5caa20deaa9b4913be9f539b2f1d8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/apl_only/requests.npz": "6b633838a29f5aee68f83e7fe97e95e5cf15063280a639114d404afb4dd5cbe8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/apl_only/spec.json": "ab07aab0cd2a76dbf73c5838ce354aefd7acafd406645f6ccd2be3d2b76abdc8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-ref.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/queue.jsonl": "4f4c79daa07526a9ac0ad39747e8083af8703edc30b1a0604b797d32c3bd4515",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/ref-history.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/requests.csv": "4b7b9294446d27af07dd591f47f69f64f037873f648e1feb3846f5aeffe1a82c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/state.npz": "0a2750ea21a095925edb6f6642777f204b176eaa717f3b0aa429f0568fb9e809",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/summary.json": "fde9a6206c089b29761374a548bea0f249f32a47fe7724f954b0c4a02d9a2d85",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/tick-state-hashes.jsonl": "a16486c0c518f2b14f65a5f4124632589cd4ce8a7819ad484206c54e5d354f16",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/input-audit.json": "96b77596cc53147b3452ef15a47dc9dc4d9bfd507e3121d8d282a6cef6c096f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/preAPL-ref.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/queue-audit.json": "88e06f99568082bc32825dd987354ca669be5a177292fa9526a1c29ccffeb512",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/queue.jsonl": "306299f8fb7e6901ce92c3e146566f8ce1f65138090daefbbe367f013d2eebaa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/ref-history.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/requests.csv": "4b7b9294446d27af07dd591f47f69f64f037873f648e1feb3846f5aeffe1a82c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/state.npz": "0a2750ea21a095925edb6f6642777f204b176eaa717f3b0aa429f0568fb9e809",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/summary.json": "3e7530b876b6095fa9d1a1171b792df41c94b720bdc948fed999cbaf315c8616",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/tick-state-hashes.jsonl": "e2936c94d40319270491846542963ea9439c94891008003edf2436366ee42e8e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/apl_only/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 0,
|
||||||
|
"requested": 2,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 11,
|
||||||
|
"accepted_requests": 3,
|
||||||
|
"active_neurons": 3,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 13,
|
||||||
|
"case": "arrival_collision",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/arrival_collision",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/arrival_collision/arrays.npz": "c256234eec74752513c95d961233e7c1a7b5caa20deaa9b4913be9f539b2f1d8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/arrival_collision/requests.npz": "2b5c4d1491dd65ac70a2e23b8d4db9be7f0798fabff114c308a753ccb58a051f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/arrival_collision/spec.json": "a80077e0d792a9aa4789d47ac69c751e5e79014a5b7f3a8f650e6147613b5feb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-drive.float32.npy": "5c00bd6558f55c0ac7b2b7dd1a3de32c1b66357de1cec433dc7e6bfb8e6650ec",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-inhibition.float32.npy": "04a2f0809f96a13a8e07649f11f546c78e4173583f599f6c8a60109df8d8005a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-state.float32.npy": "fd345540fb68691ab401b60b39daf097ed1e5667c39396575bcd8f33e23e4edf",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/g-history.float64.npy": "29b74faebbefbc54c7f307c77bf19f58c818f14fa09b60c02a309fed46c7a514",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-g.float64.npy": "eb267cf9ecd9b6ea38b081f230a2277f456896e76ed2e06b0263447db0041ab7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-ref.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-v.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/queue.jsonl": "e8f7516658bd1e671f23ffb64078207c4c9879dc28926ea0bb6ddef8c46bf066",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/ref-history.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/requests.csv": "a5be5814ce65c6b63335f0dcd801d7be567c7ae976b4f28fa0cd00f3ba74f540",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/state.npz": "1b5d50cfd92a11ccc8217bae24b6899d59d0092a75ddf90e5b74bc21ec31bc98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/summary.json": "641b1286caf31b42be66ea3197d6d7ffc34f774fa36b64e282127a0230786bbe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/tick-state-hashes.jsonl": "05ce4ee4545a3d7cd604715d7b12d460de4981feab0bb7bb6b4d563d4c657a8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/v-history.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/apl-drive.float32.npy": "5c00bd6558f55c0ac7b2b7dd1a3de32c1b66357de1cec433dc7e6bfb8e6650ec",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/apl-inhibition.float32.npy": "04a2f0809f96a13a8e07649f11f546c78e4173583f599f6c8a60109df8d8005a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/apl-state.float32.npy": "fd345540fb68691ab401b60b39daf097ed1e5667c39396575bcd8f33e23e4edf",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/g-history.float64.npy": "29b74faebbefbc54c7f307c77bf19f58c818f14fa09b60c02a309fed46c7a514",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/input-audit.json": "c83cc18f678c4ed4598b2a1cc54d7890d0ec864897beac567fc3aa88eca83baa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/preAPL-g.float64.npy": "eb267cf9ecd9b6ea38b081f230a2277f456896e76ed2e06b0263447db0041ab7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/preAPL-ref.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/preAPL-v.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/queue-audit.json": "a58959c545bba9130ebf3a44ceb662a15e9ef724f519b66dfe00e4f0dc778ef1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/queue.jsonl": "a14e60c29eee17afa66692052d5aa7661c6269785a5672ab116b9ca096a247e0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/ref-history.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/requests.csv": "a5be5814ce65c6b63335f0dcd801d7be567c7ae976b4f28fa0cd00f3ba74f540",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/state.npz": "1b5d50cfd92a11ccc8217bae24b6899d59d0092a75ddf90e5b74bc21ec31bc98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/summary.json": "696a411488e0e2039fb55aa1bc8bc26804d3ae446069a6bf9cdd64be43c73b35",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/tick-state-hashes.jsonl": "0bb726cf2815518ea4fe632d6eb162fecd1865cef54ec0fa25ba22a20f479772",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/v-history.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/arrival_collision/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 1,
|
||||||
|
"requested": 4,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 120,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 3
|
||||||
|
}
|
||||||
+204
@@ -0,0 +1,204 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 12901464,
|
||||||
|
"accepted_requests": 89,
|
||||||
|
"active_neurons": 6762,
|
||||||
|
"apl_fast_edges_zeroed": 5845,
|
||||||
|
"arriving_edges": 14055267,
|
||||||
|
"case": "cal-matched_energy-00-s51101",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/cal-matched_energy-00-s51101",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_dense_g": true,
|
||||||
|
"cpu.no_dense_ref": true,
|
||||||
|
"cpu.no_dense_v": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_dense_g": true,
|
||||||
|
"gpu.no_dense_ref": true,
|
||||||
|
"gpu.no_dense_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 25582938,
|
||||||
|
"effective_weights_raw_sha256": "b8b8f43048e0ef03943e607666319d25363bed3b2564fdc02b4149837e7eedc9",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/cal-matched_energy-00-s51101/requests.npz": "d49fb00b3870c8e923c0e5fc903536c0d8985555e5052c23ebc6f963c8af5314",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/cal-matched_energy-00-s51101/spec.json": "c6bece47f42a0a262f907d16a50ef6e12c37029f84c2184b5a15f79a7388c680",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/apl-drive.float32.npy": "664e679a6ff1d0a98a8a9c833b1bc6e5a48556487e2a181dba6a2b7db3c22f47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/apl-inhibition.float32.npy": "5c61b09f281cb180e88f7753df1537790606b8a4d3bd38af6ce47ee73e6723d4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/apl-state.float32.npy": "1912491567db6f8c9ef5d574a80a3a79e9ae22e215d9f027bd22b3afa73be185",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/queue.jsonl": "aef9236c2e4f2c511e422e73d141a292627ae33d9b465d481bb836c41525e285",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/requests.csv": "6a0fda84fe8a5640e40de7eba4a520b372a37fd9a5b6b7a28b8d2f94a0e64f33",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/state.npz": "3413e5df842dcae18784eac3fbc3ab2e5e01da74e8285e2fdee10a49f8b9eab9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/summary.json": "236bd133f1256a41f14615129c4b1809ec185d3f0d24feb7c0c154214a6d1850",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0/tick-state-hashes.jsonl": "20b2f203e16e2fc50ad79cd425afd86768dabb42d2b82f7a998dd75c01ab0a89",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/dst.npy": "ce20f7433f78442c717ad2a7b5394cf4a3b109d990b4be0788040b7b0f4ed150",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/edge_id.npy": "49260615ff2b6432ce3dea9ce2c7ab8f83d06c2fb7491e58e08355fcedf86a30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/nodes.npy": "5b511a98e8fbf8d65bbc70b93e75ecae19366f650b7842a45611bfad62ed83dc",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/ptr.npy": "fe43420f11e6242a11f8199ae7f097cab4b8a6db181d36f2a46b9e46670acbb4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/signed_raw.npy": "f9884ccb8930b32420b27c69271df78034a8350fe5a5c9b76a63c259268efc09",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/src.npy": "bfd625ce690fc21eb0a8b9dede831688ab73b789045ba83ddf4baeefeddf1fc3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/weights.npy": "462839ffc3feb8f6c278044488082b1c8e410e7f23229d6b5e29d1b7042416a1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/apl-drive.float32.npy": "664e679a6ff1d0a98a8a9c833b1bc6e5a48556487e2a181dba6a2b7db3c22f47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/apl-inhibition.float32.npy": "5c61b09f281cb180e88f7753df1537790606b8a4d3bd38af6ce47ee73e6723d4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/apl-mask-audit.json": "d0f9e4bec276cba5df66468d4052c00944c6fd9022d2d09c400e3b582e4c90b7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/apl-state.float32.npy": "1912491567db6f8c9ef5d574a80a3a79e9ae22e215d9f027bd22b3afa73be185",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/input-audit.json": "5aff1840362e079d2ec71f4094fedf7491495c50b456347397437d3c924c0758",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/queue-audit.json": "338af77057d2c3611f4dcdcf4329ec7399d9375f9bfc67a0cafe3eca2a26a6b1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/queue.jsonl": "628317164ce25c2b0b90236fe0f68d02cbcec586f9676cc03a4be1ed7e53d622",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/requests.csv": "6a0fda84fe8a5640e40de7eba4a520b372a37fd9a5b6b7a28b8d2f94a0e64f33",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/state.npz": "3413e5df842dcae18784eac3fbc3ab2e5e01da74e8285e2fdee10a49f8b9eab9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/summary.json": "d4fa203a570023c3a46da9a4ffd9b580b38141f725c992010ddc387ab558f3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/tick-state-hashes.jsonl": "7d07fe889f1f968fc83efb8d661cd6803e430dcf0914e75b2476db2e5c987396",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-matched_energy-00-s51101/weights.npy": "ac433da4b0ac3cdc20c526d99a7158c3dc2298b62c10784f9dcd7db1f089214b"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-matched_energy-00-s51101-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 166700,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": false,
|
||||||
|
"rejected_requests": 28,
|
||||||
|
"requested": 117,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 1000,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 29518
|
||||||
|
}
|
||||||
+204
@@ -0,0 +1,204 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 13165996,
|
||||||
|
"accepted_requests": 93,
|
||||||
|
"active_neurons": 6902,
|
||||||
|
"apl_fast_edges_zeroed": 5845,
|
||||||
|
"arriving_edges": 14316397,
|
||||||
|
"case": "cal-physiological-00-s51101",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/cal-physiological-00-s51101",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_dense_g": true,
|
||||||
|
"cpu.no_dense_ref": true,
|
||||||
|
"cpu.no_dense_v": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_dense_g": true,
|
||||||
|
"gpu.no_dense_ref": true,
|
||||||
|
"gpu.no_dense_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 25582938,
|
||||||
|
"effective_weights_raw_sha256": "b8b8f43048e0ef03943e607666319d25363bed3b2564fdc02b4149837e7eedc9",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/cal-physiological-00-s51101/requests.npz": "9f87b434e8da524ce31b4563ad89ab47189dc7035c9f827840f3250aad81083d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/cal-physiological-00-s51101/spec.json": "a664118cd5506ac7e093e43234a586b9c6fe06b9d9e3a2975d264975f6789bb7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/apl-drive.float32.npy": "2a492856ea680dd6509ae2e5924228744beb6f37f34c0ac0ec1ef6bdbcb7ec2a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/apl-inhibition.float32.npy": "0227a22a7c8f54321e7f02ef320a3bc22142b7efd63d9fc4a475653c86d4f025",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/apl-state.float32.npy": "fcf12e155c5922d0a93d3618205cc4828455e67f805271d8018743fe44c46721",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/queue.jsonl": "61407b2725f7074087d3eb6fbaa3910d18e544fdc061064d6205d9f992470bbe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/requests.csv": "271c9c56f9cfcb460a7856a0885f74800e54c762b881d116dcd107079b2d3e82",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/state.npz": "ea7080a05e476eb987f536ec7fb327dc78f6e2f18a7d6e4cd91601d8446ffeae",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/summary.json": "71e5049fe55738ebd42830920c605865f096c6de32bcc7d44c643fcee27e1434",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0/tick-state-hashes.jsonl": "c323832e4375fa7561d39f6b26a1439437b9650ea4ae68dbd2ed81ce4b4c4837",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/dst.npy": "ce20f7433f78442c717ad2a7b5394cf4a3b109d990b4be0788040b7b0f4ed150",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/edge_id.npy": "49260615ff2b6432ce3dea9ce2c7ab8f83d06c2fb7491e58e08355fcedf86a30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/nodes.npy": "5b511a98e8fbf8d65bbc70b93e75ecae19366f650b7842a45611bfad62ed83dc",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/ptr.npy": "fe43420f11e6242a11f8199ae7f097cab4b8a6db181d36f2a46b9e46670acbb4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/signed_raw.npy": "f9884ccb8930b32420b27c69271df78034a8350fe5a5c9b76a63c259268efc09",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/src.npy": "bfd625ce690fc21eb0a8b9dede831688ab73b789045ba83ddf4baeefeddf1fc3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full/weights.npy": "462839ffc3feb8f6c278044488082b1c8e410e7f23229d6b5e29d1b7042416a1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/apl-drive.float32.npy": "2a492856ea680dd6509ae2e5924228744beb6f37f34c0ac0ec1ef6bdbcb7ec2a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/apl-inhibition.float32.npy": "0227a22a7c8f54321e7f02ef320a3bc22142b7efd63d9fc4a475653c86d4f025",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/apl-mask-audit.json": "d0f9e4bec276cba5df66468d4052c00944c6fd9022d2d09c400e3b582e4c90b7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/apl-state.float32.npy": "fcf12e155c5922d0a93d3618205cc4828455e67f805271d8018743fe44c46721",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/input-audit.json": "0cb58f7de7ff744de6c8b6ead63c67b18ba8397aedf97d98ee2e6461e52c2745",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/queue-audit.json": "338af77057d2c3611f4dcdcf4329ec7399d9375f9bfc67a0cafe3eca2a26a6b1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/queue.jsonl": "8ed73b17d00fc6a67b807c3d36f5c9b82a974f17f1ce2d3bfd9f8d6c15de5a01",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/requests.csv": "271c9c56f9cfcb460a7856a0885f74800e54c762b881d116dcd107079b2d3e82",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/state.npz": "ea7080a05e476eb987f536ec7fb327dc78f6e2f18a7d6e4cd91601d8446ffeae",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/summary.json": "c0e9a48b851bee9032cdd16fa76f4d37c9f4b0620769edec44f882647b8dc406",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/tick-state-hashes.jsonl": "f9134739ed6a2b7558957a2bc47ad375d831b733d4c259a826e4be296bcb0cc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/cal-physiological-00-s51101/weights.npy": "ac433da4b0ac3cdc20c526d99a7158c3dc2298b62c10784f9dcd7db1f089214b"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/cal-physiological-00-s51101-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 166700,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": false,
|
||||||
|
"rejected_requests": 28,
|
||||||
|
"requested": 121,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 1000,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 29938
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 477,
|
||||||
|
"accepted_requests": 114,
|
||||||
|
"active_neurons": 44,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 1069,
|
||||||
|
"case": "high_fanin",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/high_fanin",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/high_fanin/arrays.npz": "61d667618406364f38d34a9eb2af328a74c662b17b63dc9ac33f90ab06952df7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/high_fanin/requests.npz": "817f0fb0919c87927068fb4923854e2d2bfd1f362a6401695a26127ac032e019",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/high_fanin/spec.json": "39adb14fd5ca410840d6ed69e76c818bf82545bfca62b623de67dea5fdc00164",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-drive.float32.npy": "a4b78272e91043441d6c17b2aa9844122546a0a20332cf37d08f28c324a545fb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-inhibition.float32.npy": "c1950e4c348b57a70516a73fbd7b22cef62de32b2d39ee6bce72605d6768dd50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-state.float32.npy": "951c2cc005cace059b0648d23809566f03a45d3c5e001de9c795fc84c42936b8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/g-history.float64.npy": "99a97aa123005eed480f6044dd89f28b7383db0d55b331aee8deab2d6e251b27",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-g.float64.npy": "7ba8711e0e5be02df6f88383dafb3e1a2179e2d1474ebe033e929c44fd14e073",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-ref.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-v.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/queue.jsonl": "560702d0dcc3378c188874c46af1c33c7d184317a3cba874da122d208ab0ceca",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/ref-history.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/requests.csv": "bf3a81d405fb059746c228e20ae2be2af696ff883fda09aa824cdfd9abd96f15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/state.npz": "d4408b09e7099f9293340ece2bfd381d5827829e7efb2e27f1ac8de59e70ac40",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/summary.json": "605ad105f67caba0649c96c51810cd1409e84cad3833143c80af125dded958d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/tick-state-hashes.jsonl": "f5369e924a5851f05f43ae5dfbc4e718ec6bebd478aae5b38f3ffd917e4bde6d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/v-history.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/apl-drive.float32.npy": "a4b78272e91043441d6c17b2aa9844122546a0a20332cf37d08f28c324a545fb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/apl-inhibition.float32.npy": "c1950e4c348b57a70516a73fbd7b22cef62de32b2d39ee6bce72605d6768dd50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/apl-state.float32.npy": "951c2cc005cace059b0648d23809566f03a45d3c5e001de9c795fc84c42936b8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/g-history.float64.npy": "99a97aa123005eed480f6044dd89f28b7383db0d55b331aee8deab2d6e251b27",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/input-audit.json": "5483b49feef151d1d4ede7fbfe87473cd91304d41d1b4f6803a52897b773eb3a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/preAPL-g.float64.npy": "7ba8711e0e5be02df6f88383dafb3e1a2179e2d1474ebe033e929c44fd14e073",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/preAPL-ref.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/preAPL-v.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/queue-audit.json": "2c3d786053140c64b933f23aa1e3d2192651902623e5932aac47a99198757b72",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/queue.jsonl": "02252a8546c104e0808ab55ca181e8e32c181ae9ad0ccbe13c33f008474725f6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/ref-history.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/requests.csv": "bf3a81d405fb059746c228e20ae2be2af696ff883fda09aa824cdfd9abd96f15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/state.npz": "d4408b09e7099f9293340ece2bfd381d5827829e7efb2e27f1ac8de59e70ac40",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/summary.json": "197d371f181118fc86762dee73d4b172d0acff7a10c04a7ff5703ba1f01b4b8a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/tick-state-hashes.jsonl": "badb44d874c9262789e61561fee3a5d2bc83451c7e5d1f402bfaa7b462512101",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/v-history.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/high_fanin/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 0,
|
||||||
|
"requested": 114,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 400,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 157
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 32,
|
||||||
|
"accepted_requests": 3,
|
||||||
|
"active_neurons": 2,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 35,
|
||||||
|
"case": "kc_ref_boundary",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/kc_ref_boundary",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/kc_ref_boundary/arrays.npz": "c256234eec74752513c95d961233e7c1a7b5caa20deaa9b4913be9f539b2f1d8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/kc_ref_boundary/requests.npz": "38d5b1a50b3c05c23f5652847e3598b1e7c9f9ad217442de0617054727b8c595",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/kc_ref_boundary/spec.json": "a61805aca6b71a23eb1b172bdfd49dae7a4a3631c031de693ad1e02e2fa2eb86",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-drive.float32.npy": "87b9b4d999a0ae584aafffbbce8603333b55467122495501a81fd3f396a0de15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-inhibition.float32.npy": "f915b04b78d1660e20f0f97874564454c97dc306a84ae0383cdb09b0ae5bf67f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-state.float32.npy": "db75fd304090f4d00ed3c7e5f80c14be74c0bfc99ac95984a710a3a143ef3625",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/g-history.float64.npy": "ccc182e0eabccb0dc6c5da45a11da77f7e6b899e9e2e8b9756071f2e234d4160",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-g.float64.npy": "d1780ec21ed616eee112fbf253cda4516834d54e8c8d88769e37ef02fef1851b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-ref.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-v.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/queue.jsonl": "ca3b0f706c6a010a23acce27acd5b6f534d9a2bc358d4f9e6d18f47dd552e7fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/ref-history.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/requests.csv": "92179fda232356e4cad1f94a05e0cf1c9da13299cc5e6ab5c0a0d64e77d90fc0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/state.npz": "cfabddcd199a03da9acb981c3791031d8d5926f244e3d3b5d9556133e4b23868",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/summary.json": "c9a200cdabe861ba45985d027b7766e5ef5e7f30878080ab9dd1fdc4d67ce2f3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/tick-state-hashes.jsonl": "9d681ae3b14a6b4d972aa0dcd859970b13a16757dc9db257a14657cbb651c39b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/v-history.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/apl-drive.float32.npy": "87b9b4d999a0ae584aafffbbce8603333b55467122495501a81fd3f396a0de15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/apl-inhibition.float32.npy": "f915b04b78d1660e20f0f97874564454c97dc306a84ae0383cdb09b0ae5bf67f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/apl-state.float32.npy": "db75fd304090f4d00ed3c7e5f80c14be74c0bfc99ac95984a710a3a143ef3625",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/g-history.float64.npy": "ccc182e0eabccb0dc6c5da45a11da77f7e6b899e9e2e8b9756071f2e234d4160",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/input-audit.json": "bb0d8a180e4da11732bc1da912711ed5b26db6b946d598a8f0a8d6b689867465",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/preAPL-g.float64.npy": "d1780ec21ed616eee112fbf253cda4516834d54e8c8d88769e37ef02fef1851b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/preAPL-ref.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/preAPL-v.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/queue-audit.json": "88e06f99568082bc32825dd987354ca669be5a177292fa9526a1c29ccffeb512",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/queue.jsonl": "72f55a0b9cc9bec5d5e066240b81ad6a44f85b97f0f6681f22ee5d41d459ed55",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/ref-history.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/requests.csv": "92179fda232356e4cad1f94a05e0cf1c9da13299cc5e6ab5c0a0d64e77d90fc0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/state.npz": "cfabddcd199a03da9acb981c3791031d8d5926f244e3d3b5d9556133e4b23868",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/summary.json": "96dba9ae4b6027d2342a35c8312b10a3c65e09965434cfb734d2b9a75c39eac8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/tick-state-hashes.jsonl": "6dff6c90260330994a1f5bc5862dafb0258121aaf27a6b4c28ad94b28c0ffb1d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/v-history.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/kc_ref_boundary/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 3,
|
||||||
|
"requested": 6,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 4
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 26,
|
||||||
|
"accepted_requests": 1,
|
||||||
|
"active_neurons": 2,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 27,
|
||||||
|
"case": "natural_request",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/natural_request",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/natural_request/arrays.npz": "1a4ba4d3e86b06300c645f6b02cba2d8927b8ef22003f91ccfaea39b5dc24b73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/natural_request/requests.npz": "ccaa5da628e1659f6b42a3400927cff598017d104485ca60010b45248a37eba3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/natural_request/spec.json": "7a31ef85b1f00c4710a3bbeb63faf035d2497d6d1c653392d1e9c7bc3f1585a6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-drive.float32.npy": "694944eb4e7ede2146035bd4a3725a7ca84b59a2eb499ebab036998fc05c88b4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-inhibition.float32.npy": "6652e316e26fdb7a1089fd8d586eecbb53d9643fa02c2f79722956fb70ce28d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-state.float32.npy": "1b5d2c9959509781490fd5518682f448eaaafa0737d4de841ea0b816aeac0a11",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/g-history.float64.npy": "838543584e16f2f3954c16d9aa4bd7d196acbab1bff1b4702f5cc2525bf31161",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-g.float64.npy": "b6b01f89be4922093b264f21bfcde0aac65c0faf7ceeeb55439987a78876d6a3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-ref.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-v.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/queue.jsonl": "b340f993dff712a9d47d4a4fe5bd0418d6826e5468319a98115de5cddd82b7ad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/ref-history.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/requests.csv": "53ea2ed9286427de07742f2ba22e2f8ca5f216c37e61c4b8d1506e0d90d6bbc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/state.npz": "770b7e29adbab3d29de20a77c9e3977f0da7d9cf2aaf68f346e1953683fb632c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/summary.json": "9dd57f49a08b8dc16aa76a73fad8d5beaca3a3a13c7b0b6bd3377df3b8ed22a5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/tick-state-hashes.jsonl": "4b03e6632b70d2dd056be18474c71c2ee4d202ffe212024e1001106875d5ea58",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/v-history.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/apl-drive.float32.npy": "694944eb4e7ede2146035bd4a3725a7ca84b59a2eb499ebab036998fc05c88b4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/apl-inhibition.float32.npy": "6652e316e26fdb7a1089fd8d586eecbb53d9643fa02c2f79722956fb70ce28d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/apl-state.float32.npy": "1b5d2c9959509781490fd5518682f448eaaafa0737d4de841ea0b816aeac0a11",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/g-history.float64.npy": "838543584e16f2f3954c16d9aa4bd7d196acbab1bff1b4702f5cc2525bf31161",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/input-audit.json": "d88ecadc5971ece0e6589dcd53a96cfa02f53ba27045f360ddb5c5a7342b5db1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/preAPL-g.float64.npy": "b6b01f89be4922093b264f21bfcde0aac65c0faf7ceeeb55439987a78876d6a3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/preAPL-ref.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/preAPL-v.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/queue-audit.json": "88e06f99568082bc32825dd987354ca669be5a177292fa9526a1c29ccffeb512",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/queue.jsonl": "6ed5f7b813bbae5230b8955f970ae6b0b140dd0eb33f5ea06cd2aad41f4dcae3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/ref-history.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/requests.csv": "53ea2ed9286427de07742f2ba22e2f8ca5f216c37e61c4b8d1506e0d90d6bbc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/state.npz": "770b7e29adbab3d29de20a77c9e3977f0da7d9cf2aaf68f346e1953683fb632c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/summary.json": "9f7b5059648a69618b64627a0276e0398e7a5f5bb13601be1f34699b7fa937d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/tick-state-hashes.jsonl": "66acc728c7f38ccc29f5996c3d71f23682101964c70eb1d1296b81a499fad62b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/v-history.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/natural_request/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 0,
|
||||||
|
"requested": 1,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 5,
|
||||||
|
"accepted_requests": 1,
|
||||||
|
"active_neurons": 1,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 5,
|
||||||
|
"case": "pn_pulse",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/pn_pulse",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/pn_pulse/arrays.npz": "c256234eec74752513c95d961233e7c1a7b5caa20deaa9b4913be9f539b2f1d8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/pn_pulse/requests.npz": "ac00687a2d58d91e72527f8833817588ec2caa1ad274b2694c0ef43e19bdb531",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/pn_pulse/spec.json": "ed7596015d5199d496af300b492cca1815c846c04a61c104deb613bec0aecc26",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-drive.float32.npy": "d36ee1bc57cdb36c38fefe93da0493e17dabf899b02b2222468bd67bcad5edf5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-inhibition.float32.npy": "5d3c55e13884d2a86296e3826d4ebab1ca491458fee90cbb11972b0d895c76aa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-state.float32.npy": "b680c32977a56e9551cbebef9c2d14acca31e32f44c6109a7f0b2fa90a9bb63a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/g-history.float64.npy": "883f6482df737bf45b0914680e6d6c201735d7dc2a3fbdef1d352834875ed751",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-g.float64.npy": "be91ca1c4d7e5bc4d1d77ec7bd1c2aedcf284e4181f21d8cb3c24706348e5e8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-ref.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-v.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/queue.jsonl": "530b3632adf86c3d377d47ccca60ec7f4a98ea4e16b8fb6b835951990db8bfce",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/ref-history.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/requests.csv": "4add1e0a108ad83467de9335d4ea342b47ef565b1a6f6a586c65eb9b1774a176",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/state.npz": "cd3596d06b03fc4702dea4b528c7c704659ff9316e46bdf0b804b6a3ec3b9804",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/summary.json": "c4894ccbd533402b4347c778e60b7e100f9dca625e063075a38ae95f7a56fc4d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/tick-state-hashes.jsonl": "d1e9cc90604953dd31e085a841a8b813b7f43ef20ffcda5da5fbbf1d790c72fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/v-history.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/apl-drive.float32.npy": "d36ee1bc57cdb36c38fefe93da0493e17dabf899b02b2222468bd67bcad5edf5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/apl-inhibition.float32.npy": "5d3c55e13884d2a86296e3826d4ebab1ca491458fee90cbb11972b0d895c76aa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/apl-state.float32.npy": "b680c32977a56e9551cbebef9c2d14acca31e32f44c6109a7f0b2fa90a9bb63a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/g-history.float64.npy": "883f6482df737bf45b0914680e6d6c201735d7dc2a3fbdef1d352834875ed751",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/input-audit.json": "3cea693dfe870d02e2e4b8cb954851f19c7992c59ee13a73cc5c2cf54bb5a5ed",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/preAPL-g.float64.npy": "be91ca1c4d7e5bc4d1d77ec7bd1c2aedcf284e4181f21d8cb3c24706348e5e8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/preAPL-ref.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/preAPL-v.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/queue-audit.json": "b9a0c25689f3fa01932ef97ac3f1698f6fd193a9b95b26883a44b2251a0a4d17",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/queue.jsonl": "9183c97b03f28017025534018cd82c55d5c050ed6bd9c912e36e06fe80776a98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/ref-history.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/requests.csv": "4add1e0a108ad83467de9335d4ea342b47ef565b1a6f6a586c65eb9b1774a176",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/state.npz": "cd3596d06b03fc4702dea4b528c7c704659ff9316e46bdf0b804b6a3ec3b9804",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/summary.json": "a7aa8a61ced091f8cbd0389233f60c88b1cf3454e0fd1f180b802b2dd0de14dc",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/tick-state-hashes.jsonl": "09985efa2511d1efb1b4d44002e4e0c82c63a56596453553081285396b0a0a58",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/v-history.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/pn_pulse/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 0,
|
||||||
|
"requested": 1,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 300,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 112,
|
||||||
|
"accepted_requests": 10,
|
||||||
|
"active_neurons": 4,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 118,
|
||||||
|
"case": "two_sources",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/two_sources",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/two_sources/arrays.npz": "c256234eec74752513c95d961233e7c1a7b5caa20deaa9b4913be9f539b2f1d8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/two_sources/requests.npz": "8740c2ae2faa339f222a75155f7c824b12f37ed24f2e850fcadbe70db5ebde50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/two_sources/spec.json": "0ed5a1175989b2ce7f125a9ee2ff2c70c1817133eb26cbd13a808e7c81b729c9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-drive.float32.npy": "656c1fb8a53ca1ed7c23b31f0b87a394ebca2af6e8be118d2dda6c972a5da180",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-inhibition.float32.npy": "c31530f2d09305d73bd37438ca1ed7e1d2b3cedfcfe6e4cced94279377b32081",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-state.float32.npy": "919e10a7ccb6c6ff4bd240dfe7a70f654df72068c254c63e67d8ffd6eea1ca03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/g-history.float64.npy": "b9378629d85a79968a366a61840cd7a9087c56b3b8c4f802b119abf1cfd81b30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-g.float64.npy": "3f495950e70bcc155e7b26060bdff21efb6d734e2e12c7ba9cc71f97be04c3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-ref.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-v.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/queue.jsonl": "180643201bea70bbb5d5127fcf5e7df0c198fad07a4c03d579afc79db007bf83",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/ref-history.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/requests.csv": "e60434045301b23a6e7da8907b14d0bd9e576b72ca90fae074237a8e6a20f053",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/state.npz": "ad50b02424e0dda0894e245442ae07ec02f4508ad4110795ebdd146067571975",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/summary.json": "773bcb4f7acdf4ac8863d9bc0c4fe5fc3604231e01ebb6e225c6ffbf0adcdee5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/tick-state-hashes.jsonl": "8251fe8617d284aba2ee8f764c2e0b4e990a9bc70fc65eac62fea97701187b4f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/v-history.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/apl-drive.float32.npy": "656c1fb8a53ca1ed7c23b31f0b87a394ebca2af6e8be118d2dda6c972a5da180",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/apl-inhibition.float32.npy": "c31530f2d09305d73bd37438ca1ed7e1d2b3cedfcfe6e4cced94279377b32081",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/apl-state.float32.npy": "919e10a7ccb6c6ff4bd240dfe7a70f654df72068c254c63e67d8ffd6eea1ca03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/g-history.float64.npy": "b9378629d85a79968a366a61840cd7a9087c56b3b8c4f802b119abf1cfd81b30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/input-audit.json": "043654cddb58aaf498828799f9a776b96aea0d16ddf48852c1aa3a0a8062d482",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/preAPL-g.float64.npy": "3f495950e70bcc155e7b26060bdff21efb6d734e2e12c7ba9cc71f97be04c3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/preAPL-ref.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/preAPL-v.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/queue-audit.json": "b9a0c25689f3fa01932ef97ac3f1698f6fd193a9b95b26883a44b2251a0a4d17",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/queue.jsonl": "b5af9041389ca83f9054622b9b515a27f74c85848d039fcfa78959f34924821d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/ref-history.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/requests.csv": "e60434045301b23a6e7da8907b14d0bd9e576b72ca90fae074237a8e6a20f053",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/state.npz": "ad50b02424e0dda0894e245442ae07ec02f4508ad4110795ebdd146067571975",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/summary.json": "60f3d0278419f59521d5a111c93a8ada37a3be2d7297e34ff18f3516a03cd24c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/tick-state-hashes.jsonl": "77167ce3a937b862b0876c8cda1588e7bdfa88825f59dda3788c9a4610b29e9e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/v-history.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/two_sources/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 0,
|
||||||
|
"requested": 10,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 300,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 13
|
||||||
|
}
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
{
|
||||||
|
"accepted_arriving_edges": 0,
|
||||||
|
"accepted_requests": 0,
|
||||||
|
"active_neurons": 0,
|
||||||
|
"apl_fast_edges_zeroed": 50,
|
||||||
|
"arriving_edges": 0,
|
||||||
|
"case": "zero",
|
||||||
|
"case_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/zero",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"cpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"cpu.actual_author_coefficients_exact": true,
|
||||||
|
"cpu.actual_component_bundle_bytes": true,
|
||||||
|
"cpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"cpu.apl_fast_edge_count": true,
|
||||||
|
"cpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_ref.finite": true,
|
||||||
|
"cpu.apl_keeps_ref.schema": true,
|
||||||
|
"cpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"cpu.apl_keeps_voltage.finite": true,
|
||||||
|
"cpu.apl_keeps_voltage.schema": true,
|
||||||
|
"cpu.apl_positive_drive": true,
|
||||||
|
"cpu.apl_positive_inhibition": true,
|
||||||
|
"cpu.apl_positive_state": true,
|
||||||
|
"cpu.apl_precision": true,
|
||||||
|
"cpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"cpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"cpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"cpu.bundle_hashes": true,
|
||||||
|
"cpu.case_name": true,
|
||||||
|
"cpu.coefficient_input_hash": true,
|
||||||
|
"cpu.component_dimensions_clock": true,
|
||||||
|
"cpu.component_precision_environment": true,
|
||||||
|
"cpu.count_nonnegative_total": true,
|
||||||
|
"cpu.delayed_all_edges_count": true,
|
||||||
|
"cpu.effective_weights_independent_bytes": true,
|
||||||
|
"cpu.effective_weights_raw_sha": true,
|
||||||
|
"cpu.events_per_neuron_counts": true,
|
||||||
|
"cpu.events_sorted_unique": true,
|
||||||
|
"cpu.frozen_apl_constants": true,
|
||||||
|
"cpu.graph_hashes": true,
|
||||||
|
"cpu.history_final_g": true,
|
||||||
|
"cpu.history_final_ref": true,
|
||||||
|
"cpu.history_final_v": true,
|
||||||
|
"cpu.history_hashes_g": true,
|
||||||
|
"cpu.history_hashes_ref": true,
|
||||||
|
"cpu.history_hashes_v": true,
|
||||||
|
"cpu.history_mode": true,
|
||||||
|
"cpu.kc_target_count": true,
|
||||||
|
"cpu.last_hash_g": true,
|
||||||
|
"cpu.last_hash_ref": true,
|
||||||
|
"cpu.last_hash_v": true,
|
||||||
|
"cpu.mask_provenance": true,
|
||||||
|
"cpu.no_candidate_trace_input": true,
|
||||||
|
"cpu.no_error_marker": true,
|
||||||
|
"cpu.pinned_environment": true,
|
||||||
|
"cpu.queue_observer_coverage": true,
|
||||||
|
"cpu.read_actual_case": true,
|
||||||
|
"cpu.ref_range": true,
|
||||||
|
"cpu.reported_events": true,
|
||||||
|
"cpu.request_refractory_gate": true,
|
||||||
|
"cpu.request_summary": true,
|
||||||
|
"cpu.requests_match_frozen_input": true,
|
||||||
|
"cpu.sidecar_complete": true,
|
||||||
|
"cpu.small_queue_independent_reconstruction": true,
|
||||||
|
"cpu.spike_g_reset_before_apl": true,
|
||||||
|
"cpu.summary_complete": true,
|
||||||
|
"cpu.worker_source_hash": true,
|
||||||
|
"gpu.accepted_spikes_rejected_absent": true,
|
||||||
|
"gpu.actual_component_bundle_bytes": true,
|
||||||
|
"gpu.all_ref_hashes_from_actual_events": true,
|
||||||
|
"gpu.apl_fast_edge_count": true,
|
||||||
|
"gpu.apl_keeps_ref.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_ref.finite": true,
|
||||||
|
"gpu.apl_keeps_ref.schema": true,
|
||||||
|
"gpu.apl_keeps_voltage.bitwise_exact": true,
|
||||||
|
"gpu.apl_keeps_voltage.finite": true,
|
||||||
|
"gpu.apl_keeps_voltage.schema": true,
|
||||||
|
"gpu.apl_positive_drive": true,
|
||||||
|
"gpu.apl_positive_inhibition": true,
|
||||||
|
"gpu.apl_positive_state": true,
|
||||||
|
"gpu.apl_precision": true,
|
||||||
|
"gpu.apl_unconditional_g_write.bitwise_exact": true,
|
||||||
|
"gpu.apl_unconditional_g_write.finite": true,
|
||||||
|
"gpu.apl_unconditional_g_write.schema": true,
|
||||||
|
"gpu.case_name": true,
|
||||||
|
"gpu.component_dimensions_clock": true,
|
||||||
|
"gpu.component_precision_environment": true,
|
||||||
|
"gpu.component_summary_consistent": true,
|
||||||
|
"gpu.count_nonnegative_total": true,
|
||||||
|
"gpu.delayed_all_edges_count": true,
|
||||||
|
"gpu.effective_weights_raw_sha": true,
|
||||||
|
"gpu.events_per_neuron_counts": true,
|
||||||
|
"gpu.events_sorted_unique": true,
|
||||||
|
"gpu.frozen_apl_constants": true,
|
||||||
|
"gpu.history_final_g": true,
|
||||||
|
"gpu.history_final_ref": true,
|
||||||
|
"gpu.history_final_v": true,
|
||||||
|
"gpu.history_hashes_g": true,
|
||||||
|
"gpu.history_hashes_ref": true,
|
||||||
|
"gpu.history_hashes_v": true,
|
||||||
|
"gpu.history_mode": true,
|
||||||
|
"gpu.input_hashes": true,
|
||||||
|
"gpu.kc_target_count": true,
|
||||||
|
"gpu.last_hash_g": true,
|
||||||
|
"gpu.last_hash_ref": true,
|
||||||
|
"gpu.last_hash_v": true,
|
||||||
|
"gpu.no_error_marker": true,
|
||||||
|
"gpu.ref_range": true,
|
||||||
|
"gpu.reported_events": true,
|
||||||
|
"gpu.request_refractory_gate": true,
|
||||||
|
"gpu.request_summary": true,
|
||||||
|
"gpu.requests_match_frozen_input": true,
|
||||||
|
"gpu.small_queue_independent_reconstruction": true,
|
||||||
|
"gpu.spike_g_reset_before_apl": true,
|
||||||
|
"gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true
|
||||||
|
},
|
||||||
|
"component_environment": {
|
||||||
|
"CUBLAS_WORKSPACE_CONFIG": null,
|
||||||
|
"cuda": "13.0",
|
||||||
|
"cuda_matmul_allow_tf32": false,
|
||||||
|
"cudnn": 92400,
|
||||||
|
"cudnn_allow_tf32": true,
|
||||||
|
"cudnn_benchmark": false,
|
||||||
|
"cudnn_deterministic": false,
|
||||||
|
"deterministic_algorithms": false,
|
||||||
|
"device_capability": [
|
||||||
|
8,
|
||||||
|
9
|
||||||
|
],
|
||||||
|
"device_index": 0,
|
||||||
|
"device_name": "NVIDIA GeForce RTX 4090",
|
||||||
|
"float32_matmul_precision": "highest",
|
||||||
|
"numpy": "2.2.6",
|
||||||
|
"precision_configuration_changed_by_component": false,
|
||||||
|
"torch": "2.14.0+cu130"
|
||||||
|
},
|
||||||
|
"cpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero",
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"effective_weights_raw_sha256": "4f55a48a0b1e07e26b5fa132bb6a9ed87194f254ab832b4c7e9657b52cd375c6",
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/apl_globals.npy": "8388c8795d49cfe5b14fda54f76ef3a35030c62ba87bd8ca6334a2dcdf186f19",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/input_matrix.npy": "c4d3df703ea5f1d7402b8255cfa19d9744139ad1048827c23b151d8ba766fec6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/kc_globals.npy": "97a570aafa089f93e642b2bb07e3a3322dabb14c3c7dd431f0c8d2b3b7951fdd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle/output_matrix.npy": "e2d0a1ccd740e6777245ebf2efcd88bf5e1da9e47308c63ec8e83d451e134a73",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/zero/arrays.npz": "c256234eec74752513c95d961233e7c1a7b5caa20deaa9b4913be9f539b2f1d8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/zero/requests.npz": "517b500f350b0825f7cc9c639beb62d06764de286b13e0835cb26c5f83ff106a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/cases/zero/spec.json": "ca4f0859761882b54abfc2390669b7a5ef9a70c4e97b915dc90754443ff8b663",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-ref.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/queue.jsonl": "c6ba176eb2004b9cf5e7df65a7989630c37c04b8933b5d79ab89febcc82f955a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/ref-history.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/requests.csv": "d2250de77a7723e0237f53b54038377b5502ccf3a549cc08f3344a1e924b99ac",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/state.npz": "acf8be16ad5ac4fab3a0fb96cd1b322b86cb0089f506f57a7d4a6043f4e18dff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/summary.json": "737fba9a39f9c30a2e4e337df01f1fc30ad482ca0357c8a3c8cd92170f2e35db",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/tick-state-hashes.jsonl": "e65f6ff485f0ac45811c9d9cea7183f89609dc5e2740fe183f0861cb3e1c6dad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/dst.npy": "6f50ad492013b3d14fe45c46210a68c37fb138337ae7f91eed0730f92d5cc7d6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/edge_id.npy": "8b3ad7ca57738feb1495d75dadb7c7cd62890ab0b763bfb46ed217d4002c8765",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/nodes.npy": "2a65c268f42ecb99ce2a30a22f0b654a0101ab1f336388bc2e96dc7057ccc0bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/ptr.npy": "98f301cd19c6e01a911249cc594431369ed593b686f870c24aee86fcb41c8f81",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/signed_raw.npy": "8af7fa8ede8c3da396d00bee2146d01cd549c065702d8e27211df73ad1a32471",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/src.npy": "98ccabc84a7a57fa01a92f7164e5333dbe3f90bf18efbccf3cb4f40fef326a5f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures/weights.npy": "d751ac5a580f88071e5a876882ada072aeb8e461f76e4fbca4ad41fa4b14f865",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/apl-mask-audit.json": "9e0270f62e8bcd6ddd98e23a144d438f230eb7913e5039e90324b14f79647715",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/apl-worker-handshake.json": "9850e95638c94a6855533152c91b1f50430cd2b68ca2b47381a0ec5d99d0e1f0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/coefficients.json": "bde79d95ef0097b827d5faf4d5658eafc009d8e9fcef1fddd645c953823e3f64",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/environment.json": "16ec485d45d573738f9e62d74d7dc5a2cf130320472e2cedcca645dad2c5983c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/input-audit.json": "3c4c3626cdddaf2efae8b5a6f26df6de27179612bfd1530fedd6f263ba0e7adb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/preAPL-ref.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/queue-audit.json": "88e06f99568082bc32825dd987354ca669be5a177292fa9526a1c29ccffeb512",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/queue.jsonl": "487cd06e47971aef19030eba81cd910a252354752fe9d275857d832420f28c86",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/ref-history.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/requests.csv": "d2250de77a7723e0237f53b54038377b5502ccf3a549cc08f3344a1e924b99ac",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/state.npz": "acf8be16ad5ac4fab3a0fb96cd1b322b86cb0089f506f57a7d4a6043f4e18dff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/summary.json": "3112086a399799ffa0218a9473044d24939a8619b47dcff2e8572c6a3bd1cfce",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/tick-state-hashes.jsonl": "351b5dfaad76fd9bfacb230a8d131d9d0b1af41771d49c50c1278d6b398d010d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/oracle/zero/weights.npy": "815a82e033b1f70f42595c15ad36677692521bde0befc558c34cfab624b38406"
|
||||||
|
},
|
||||||
|
"failed_checks": [],
|
||||||
|
"gpu_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0",
|
||||||
|
"independent_CPU_all_components_claim": false,
|
||||||
|
"kind": "shared-APL-component closed-loop byte-exact comparison",
|
||||||
|
"limits": [
|
||||||
|
"APL Torch primitives are shared; original AST component validation is a separate required gate.",
|
||||||
|
"Small cases preserve and independently hash all pre/post states; full cases compare all-tick instrumented state hashes without saving dense whole-brain histories.",
|
||||||
|
"For full cases intermediate finite checks are performed by the instrumented backends; this file independently inspects final states and all APL traces.",
|
||||||
|
"This is exact agreement for the declared trajectory, not physiological validity or learning."
|
||||||
|
],
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"rejected_requests": 0,
|
||||||
|
"requested": 0,
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 0
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"pass_all": true,
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"case": "zero",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "pn_pulse",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "kc_ref_boundary",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "two_sources",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "arrival_collision",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "natural_request",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "apl_only",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "high_fanin",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scope": "Fixed real-edge induced fixtures only"
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"pass_all": true,
|
||||||
|
"cases": [
|
||||||
|
{
|
||||||
|
"case": "cal-physiological-00-s51101",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"case": "cal-matched_energy-00-s51101",
|
||||||
|
"pass_all": true,
|
||||||
|
"gpu_repeats": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scope": "Only two original first-CAL fixed fullgraph trajectories"
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "apl_only",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-ref.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/queue.jsonl": "4f4c79daa07526a9ac0ad39747e8083af8703edc30b1a0604b797d32c3bd4515",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/ref-history.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/requests.csv": "4b7b9294446d27af07dd591f47f69f64f037873f648e1feb3846f5aeffe1a82c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/state.npz": "0a2750ea21a095925edb6f6642777f204b176eaa717f3b0aa429f0568fb9e809",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/summary.json": "fde9a6206c089b29761374a548bea0f249f32a47fe7724f954b0c4a02d9a2d85",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/tick-state-hashes.jsonl": "a16486c0c518f2b14f65a5f4124632589cd4ce8a7819ad484206c54e5d354f16",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/preAPL-ref.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/queue.jsonl": "4f4c79daa07526a9ac0ad39747e8083af8703edc30b1a0604b797d32c3bd4515",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/ref-history.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/requests.csv": "4b7b9294446d27af07dd591f47f69f64f037873f648e1feb3846f5aeffe1a82c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/state.npz": "0a2750ea21a095925edb6f6642777f204b176eaa717f3b0aa429f0568fb9e809",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/summary.json": "6c0e8cbcb33d3fa1145d5c3a7f719e5c09ad400e1446a58e8e721342248d446f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/tick-state-hashes.jsonl": "a16486c0c518f2b14f65a5f4124632589cd4ce8a7819ad484206c54e5d354f16",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "apl_only",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-ref.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/queue.jsonl": "4f4c79daa07526a9ac0ad39747e8083af8703edc30b1a0604b797d32c3bd4515",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/ref-history.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/requests.csv": "4b7b9294446d27af07dd591f47f69f64f037873f648e1feb3846f5aeffe1a82c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/state.npz": "0a2750ea21a095925edb6f6642777f204b176eaa717f3b0aa429f0568fb9e809",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/summary.json": "fde9a6206c089b29761374a548bea0f249f32a47fe7724f954b0c4a02d9a2d85",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/tick-state-hashes.jsonl": "a16486c0c518f2b14f65a5f4124632589cd4ce8a7819ad484206c54e5d354f16",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/preAPL-ref.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/queue.jsonl": "4f4c79daa07526a9ac0ad39747e8083af8703edc30b1a0604b797d32c3bd4515",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/ref-history.int32.npy": "ec083acdde14d59546400d8fadf86efad6208b86098ef6eb96b38d533433d54b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/requests.csv": "4b7b9294446d27af07dd591f47f69f64f037873f648e1feb3846f5aeffe1a82c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/state.npz": "0a2750ea21a095925edb6f6642777f204b176eaa717f3b0aa429f0568fb9e809",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/summary.json": "06aec603bd59d6e5c74d067822a21d30438f448090abd34516fb9236b6821c5a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/tick-state-hashes.jsonl": "a16486c0c518f2b14f65a5f4124632589cd4ce8a7819ad484206c54e5d354f16",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/apl_only-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "arrival_collision",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-drive.float32.npy": "5c00bd6558f55c0ac7b2b7dd1a3de32c1b66357de1cec433dc7e6bfb8e6650ec",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-inhibition.float32.npy": "04a2f0809f96a13a8e07649f11f546c78e4173583f599f6c8a60109df8d8005a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-state.float32.npy": "fd345540fb68691ab401b60b39daf097ed1e5667c39396575bcd8f33e23e4edf",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/g-history.float64.npy": "29b74faebbefbc54c7f307c77bf19f58c818f14fa09b60c02a309fed46c7a514",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-g.float64.npy": "eb267cf9ecd9b6ea38b081f230a2277f456896e76ed2e06b0263447db0041ab7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-ref.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-v.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/queue.jsonl": "e8f7516658bd1e671f23ffb64078207c4c9879dc28926ea0bb6ddef8c46bf066",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/ref-history.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/requests.csv": "a5be5814ce65c6b63335f0dcd801d7be567c7ae976b4f28fa0cd00f3ba74f540",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/state.npz": "1b5d50cfd92a11ccc8217bae24b6899d59d0092a75ddf90e5b74bc21ec31bc98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/summary.json": "641b1286caf31b42be66ea3197d6d7ffc34f774fa36b64e282127a0230786bbe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/tick-state-hashes.jsonl": "05ce4ee4545a3d7cd604715d7b12d460de4981feab0bb7bb6b4d563d4c657a8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/v-history.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/apl-drive.float32.npy": "5c00bd6558f55c0ac7b2b7dd1a3de32c1b66357de1cec433dc7e6bfb8e6650ec",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/apl-inhibition.float32.npy": "04a2f0809f96a13a8e07649f11f546c78e4173583f599f6c8a60109df8d8005a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/apl-state.float32.npy": "fd345540fb68691ab401b60b39daf097ed1e5667c39396575bcd8f33e23e4edf",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/g-history.float64.npy": "29b74faebbefbc54c7f307c77bf19f58c818f14fa09b60c02a309fed46c7a514",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/preAPL-g.float64.npy": "eb267cf9ecd9b6ea38b081f230a2277f456896e76ed2e06b0263447db0041ab7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/preAPL-ref.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/preAPL-v.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/queue.jsonl": "e8f7516658bd1e671f23ffb64078207c4c9879dc28926ea0bb6ddef8c46bf066",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/ref-history.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/requests.csv": "a5be5814ce65c6b63335f0dcd801d7be567c7ae976b4f28fa0cd00f3ba74f540",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/state.npz": "1b5d50cfd92a11ccc8217bae24b6899d59d0092a75ddf90e5b74bc21ec31bc98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/summary.json": "94bdedc9662682f60dfa900655665cebeb7caf722607a732a57b16f7abe65ca8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/tick-state-hashes.jsonl": "05ce4ee4545a3d7cd604715d7b12d460de4981feab0bb7bb6b4d563d4c657a8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1/v-history.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 120,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 3
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "arrival_collision",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-drive.float32.npy": "5c00bd6558f55c0ac7b2b7dd1a3de32c1b66357de1cec433dc7e6bfb8e6650ec",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-inhibition.float32.npy": "04a2f0809f96a13a8e07649f11f546c78e4173583f599f6c8a60109df8d8005a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/apl-state.float32.npy": "fd345540fb68691ab401b60b39daf097ed1e5667c39396575bcd8f33e23e4edf",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/g-history.float64.npy": "29b74faebbefbc54c7f307c77bf19f58c818f14fa09b60c02a309fed46c7a514",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-g.float64.npy": "eb267cf9ecd9b6ea38b081f230a2277f456896e76ed2e06b0263447db0041ab7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-ref.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/preAPL-v.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/queue.jsonl": "e8f7516658bd1e671f23ffb64078207c4c9879dc28926ea0bb6ddef8c46bf066",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/ref-history.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/requests.csv": "a5be5814ce65c6b63335f0dcd801d7be567c7ae976b4f28fa0cd00f3ba74f540",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/state.npz": "1b5d50cfd92a11ccc8217bae24b6899d59d0092a75ddf90e5b74bc21ec31bc98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/summary.json": "641b1286caf31b42be66ea3197d6d7ffc34f774fa36b64e282127a0230786bbe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/tick-state-hashes.jsonl": "05ce4ee4545a3d7cd604715d7b12d460de4981feab0bb7bb6b4d563d4c657a8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0/v-history.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/apl-drive.float32.npy": "5c00bd6558f55c0ac7b2b7dd1a3de32c1b66357de1cec433dc7e6bfb8e6650ec",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/apl-inhibition.float32.npy": "04a2f0809f96a13a8e07649f11f546c78e4173583f599f6c8a60109df8d8005a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/apl-state.float32.npy": "fd345540fb68691ab401b60b39daf097ed1e5667c39396575bcd8f33e23e4edf",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/g-history.float64.npy": "29b74faebbefbc54c7f307c77bf19f58c818f14fa09b60c02a309fed46c7a514",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/preAPL-g.float64.npy": "eb267cf9ecd9b6ea38b081f230a2277f456896e76ed2e06b0263447db0041ab7",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/preAPL-ref.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/preAPL-v.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/queue.jsonl": "e8f7516658bd1e671f23ffb64078207c4c9879dc28926ea0bb6ddef8c46bf066",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/ref-history.int32.npy": "ebe5ab03b4ba2d49c54082440a5ed5caf977081c2cce4ad212d61bb3f6dd41b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/requests.csv": "a5be5814ce65c6b63335f0dcd801d7be567c7ae976b4f28fa0cd00f3ba74f540",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/state.npz": "1b5d50cfd92a11ccc8217bae24b6899d59d0092a75ddf90e5b74bc21ec31bc98",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/summary.json": "ada3fe560fe1a3d59ba54682d2078a29a53497653c1d7b1a5b587abf84a54a03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/tick-state-hashes.jsonl": "05ce4ee4545a3d7cd604715d7b12d460de4981feab0bb7bb6b4d563d4c657a8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2/v-history.float64.npy": "8b68b29c4dee360b82283bcfce5159740dd7458db7ebd88f0a70fc80b605e18a"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/arrival_collision-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 120,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 3
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "high_fanin",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-drive.float32.npy": "a4b78272e91043441d6c17b2aa9844122546a0a20332cf37d08f28c324a545fb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-inhibition.float32.npy": "c1950e4c348b57a70516a73fbd7b22cef62de32b2d39ee6bce72605d6768dd50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-state.float32.npy": "951c2cc005cace059b0648d23809566f03a45d3c5e001de9c795fc84c42936b8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/g-history.float64.npy": "99a97aa123005eed480f6044dd89f28b7383db0d55b331aee8deab2d6e251b27",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-g.float64.npy": "7ba8711e0e5be02df6f88383dafb3e1a2179e2d1474ebe033e929c44fd14e073",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-ref.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-v.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/queue.jsonl": "560702d0dcc3378c188874c46af1c33c7d184317a3cba874da122d208ab0ceca",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/ref-history.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/requests.csv": "bf3a81d405fb059746c228e20ae2be2af696ff883fda09aa824cdfd9abd96f15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/state.npz": "d4408b09e7099f9293340ece2bfd381d5827829e7efb2e27f1ac8de59e70ac40",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/summary.json": "605ad105f67caba0649c96c51810cd1409e84cad3833143c80af125dded958d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/tick-state-hashes.jsonl": "f5369e924a5851f05f43ae5dfbc4e718ec6bebd478aae5b38f3ffd917e4bde6d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/v-history.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/apl-drive.float32.npy": "a4b78272e91043441d6c17b2aa9844122546a0a20332cf37d08f28c324a545fb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/apl-inhibition.float32.npy": "c1950e4c348b57a70516a73fbd7b22cef62de32b2d39ee6bce72605d6768dd50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/apl-state.float32.npy": "951c2cc005cace059b0648d23809566f03a45d3c5e001de9c795fc84c42936b8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/g-history.float64.npy": "99a97aa123005eed480f6044dd89f28b7383db0d55b331aee8deab2d6e251b27",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/preAPL-g.float64.npy": "7ba8711e0e5be02df6f88383dafb3e1a2179e2d1474ebe033e929c44fd14e073",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/preAPL-ref.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/preAPL-v.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/queue.jsonl": "560702d0dcc3378c188874c46af1c33c7d184317a3cba874da122d208ab0ceca",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/ref-history.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/requests.csv": "bf3a81d405fb059746c228e20ae2be2af696ff883fda09aa824cdfd9abd96f15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/state.npz": "d4408b09e7099f9293340ece2bfd381d5827829e7efb2e27f1ac8de59e70ac40",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/summary.json": "348dc02e3e94447fb9b70187f52e075eb19e201af2b146c3ad4c417da44c27b5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/tick-state-hashes.jsonl": "f5369e924a5851f05f43ae5dfbc4e718ec6bebd478aae5b38f3ffd917e4bde6d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1/v-history.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 400,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 157
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "high_fanin",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-drive.float32.npy": "a4b78272e91043441d6c17b2aa9844122546a0a20332cf37d08f28c324a545fb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-inhibition.float32.npy": "c1950e4c348b57a70516a73fbd7b22cef62de32b2d39ee6bce72605d6768dd50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/apl-state.float32.npy": "951c2cc005cace059b0648d23809566f03a45d3c5e001de9c795fc84c42936b8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/g-history.float64.npy": "99a97aa123005eed480f6044dd89f28b7383db0d55b331aee8deab2d6e251b27",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-g.float64.npy": "7ba8711e0e5be02df6f88383dafb3e1a2179e2d1474ebe033e929c44fd14e073",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-ref.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/preAPL-v.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/queue.jsonl": "560702d0dcc3378c188874c46af1c33c7d184317a3cba874da122d208ab0ceca",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/ref-history.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/requests.csv": "bf3a81d405fb059746c228e20ae2be2af696ff883fda09aa824cdfd9abd96f15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/state.npz": "d4408b09e7099f9293340ece2bfd381d5827829e7efb2e27f1ac8de59e70ac40",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/summary.json": "605ad105f67caba0649c96c51810cd1409e84cad3833143c80af125dded958d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/tick-state-hashes.jsonl": "f5369e924a5851f05f43ae5dfbc4e718ec6bebd478aae5b38f3ffd917e4bde6d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0/v-history.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/apl-drive.float32.npy": "a4b78272e91043441d6c17b2aa9844122546a0a20332cf37d08f28c324a545fb",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/apl-inhibition.float32.npy": "c1950e4c348b57a70516a73fbd7b22cef62de32b2d39ee6bce72605d6768dd50",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/apl-state.float32.npy": "951c2cc005cace059b0648d23809566f03a45d3c5e001de9c795fc84c42936b8",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/g-history.float64.npy": "99a97aa123005eed480f6044dd89f28b7383db0d55b331aee8deab2d6e251b27",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/preAPL-g.float64.npy": "7ba8711e0e5be02df6f88383dafb3e1a2179e2d1474ebe033e929c44fd14e073",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/preAPL-ref.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/preAPL-v.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/queue.jsonl": "560702d0dcc3378c188874c46af1c33c7d184317a3cba874da122d208ab0ceca",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/ref-history.int32.npy": "9f4e23548c9837c5a1d3556a0d4eb6dffbc290d750c29975cdb99c6cd16fee43",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/requests.csv": "bf3a81d405fb059746c228e20ae2be2af696ff883fda09aa824cdfd9abd96f15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/state.npz": "d4408b09e7099f9293340ece2bfd381d5827829e7efb2e27f1ac8de59e70ac40",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/summary.json": "30b2b085e7f40cade285989f34e7ac96c9dd9308f164624bad4774bba185c2ff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/tick-state-hashes.jsonl": "f5369e924a5851f05f43ae5dfbc4e718ec6bebd478aae5b38f3ffd917e4bde6d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2/v-history.float64.npy": "4922a40c915ea3a0b92287a7dd9505e8ef6a9182c28961bd6c844c5631567ed2"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/high_fanin-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 400,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 157
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "kc_ref_boundary",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-drive.float32.npy": "87b9b4d999a0ae584aafffbbce8603333b55467122495501a81fd3f396a0de15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-inhibition.float32.npy": "f915b04b78d1660e20f0f97874564454c97dc306a84ae0383cdb09b0ae5bf67f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-state.float32.npy": "db75fd304090f4d00ed3c7e5f80c14be74c0bfc99ac95984a710a3a143ef3625",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/g-history.float64.npy": "ccc182e0eabccb0dc6c5da45a11da77f7e6b899e9e2e8b9756071f2e234d4160",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-g.float64.npy": "d1780ec21ed616eee112fbf253cda4516834d54e8c8d88769e37ef02fef1851b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-ref.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-v.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/queue.jsonl": "ca3b0f706c6a010a23acce27acd5b6f534d9a2bc358d4f9e6d18f47dd552e7fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/ref-history.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/requests.csv": "92179fda232356e4cad1f94a05e0cf1c9da13299cc5e6ab5c0a0d64e77d90fc0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/state.npz": "cfabddcd199a03da9acb981c3791031d8d5926f244e3d3b5d9556133e4b23868",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/summary.json": "c9a200cdabe861ba45985d027b7766e5ef5e7f30878080ab9dd1fdc4d67ce2f3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/tick-state-hashes.jsonl": "9d681ae3b14a6b4d972aa0dcd859970b13a16757dc9db257a14657cbb651c39b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/v-history.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/apl-drive.float32.npy": "87b9b4d999a0ae584aafffbbce8603333b55467122495501a81fd3f396a0de15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/apl-inhibition.float32.npy": "f915b04b78d1660e20f0f97874564454c97dc306a84ae0383cdb09b0ae5bf67f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/apl-state.float32.npy": "db75fd304090f4d00ed3c7e5f80c14be74c0bfc99ac95984a710a3a143ef3625",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/g-history.float64.npy": "ccc182e0eabccb0dc6c5da45a11da77f7e6b899e9e2e8b9756071f2e234d4160",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/preAPL-g.float64.npy": "d1780ec21ed616eee112fbf253cda4516834d54e8c8d88769e37ef02fef1851b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/preAPL-ref.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/preAPL-v.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/queue.jsonl": "ca3b0f706c6a010a23acce27acd5b6f534d9a2bc358d4f9e6d18f47dd552e7fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/ref-history.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/requests.csv": "92179fda232356e4cad1f94a05e0cf1c9da13299cc5e6ab5c0a0d64e77d90fc0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/state.npz": "cfabddcd199a03da9acb981c3791031d8d5926f244e3d3b5d9556133e4b23868",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/summary.json": "5b12cc0f5581bf16e15ffe0e02d2736860a94f041f5e60c1e3745677d35cfede",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/tick-state-hashes.jsonl": "9d681ae3b14a6b4d972aa0dcd859970b13a16757dc9db257a14657cbb651c39b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1/v-history.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 4
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "kc_ref_boundary",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-drive.float32.npy": "87b9b4d999a0ae584aafffbbce8603333b55467122495501a81fd3f396a0de15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-inhibition.float32.npy": "f915b04b78d1660e20f0f97874564454c97dc306a84ae0383cdb09b0ae5bf67f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/apl-state.float32.npy": "db75fd304090f4d00ed3c7e5f80c14be74c0bfc99ac95984a710a3a143ef3625",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/g-history.float64.npy": "ccc182e0eabccb0dc6c5da45a11da77f7e6b899e9e2e8b9756071f2e234d4160",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-g.float64.npy": "d1780ec21ed616eee112fbf253cda4516834d54e8c8d88769e37ef02fef1851b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-ref.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/preAPL-v.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/queue.jsonl": "ca3b0f706c6a010a23acce27acd5b6f534d9a2bc358d4f9e6d18f47dd552e7fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/ref-history.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/requests.csv": "92179fda232356e4cad1f94a05e0cf1c9da13299cc5e6ab5c0a0d64e77d90fc0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/state.npz": "cfabddcd199a03da9acb981c3791031d8d5926f244e3d3b5d9556133e4b23868",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/summary.json": "c9a200cdabe861ba45985d027b7766e5ef5e7f30878080ab9dd1fdc4d67ce2f3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/tick-state-hashes.jsonl": "9d681ae3b14a6b4d972aa0dcd859970b13a16757dc9db257a14657cbb651c39b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0/v-history.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/apl-drive.float32.npy": "87b9b4d999a0ae584aafffbbce8603333b55467122495501a81fd3f396a0de15",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/apl-inhibition.float32.npy": "f915b04b78d1660e20f0f97874564454c97dc306a84ae0383cdb09b0ae5bf67f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/apl-state.float32.npy": "db75fd304090f4d00ed3c7e5f80c14be74c0bfc99ac95984a710a3a143ef3625",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/g-history.float64.npy": "ccc182e0eabccb0dc6c5da45a11da77f7e6b899e9e2e8b9756071f2e234d4160",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/preAPL-g.float64.npy": "d1780ec21ed616eee112fbf253cda4516834d54e8c8d88769e37ef02fef1851b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/preAPL-ref.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/preAPL-v.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/queue.jsonl": "ca3b0f706c6a010a23acce27acd5b6f534d9a2bc358d4f9e6d18f47dd552e7fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/ref-history.int32.npy": "6f9db25e4040afede269f93817489b703fe32b02b36b8ab27cba239e53f00b47",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/requests.csv": "92179fda232356e4cad1f94a05e0cf1c9da13299cc5e6ab5c0a0d64e77d90fc0",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/state.npz": "cfabddcd199a03da9acb981c3791031d8d5926f244e3d3b5d9556133e4b23868",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/summary.json": "e98094d7bb03ebeeffac3d3438b2d0c86db32169efbbfbd260212d2a17dbf748",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/tick-state-hashes.jsonl": "9d681ae3b14a6b4d972aa0dcd859970b13a16757dc9db257a14657cbb651c39b",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2/v-history.float64.npy": "2e230205d7fd80d884c63c7a9c8879b02c77f8946f5e72e5c49e9a852a0fce3e"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/kc_ref_boundary-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 4
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "natural_request",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-drive.float32.npy": "694944eb4e7ede2146035bd4a3725a7ca84b59a2eb499ebab036998fc05c88b4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-inhibition.float32.npy": "6652e316e26fdb7a1089fd8d586eecbb53d9643fa02c2f79722956fb70ce28d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-state.float32.npy": "1b5d2c9959509781490fd5518682f448eaaafa0737d4de841ea0b816aeac0a11",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/g-history.float64.npy": "838543584e16f2f3954c16d9aa4bd7d196acbab1bff1b4702f5cc2525bf31161",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-g.float64.npy": "b6b01f89be4922093b264f21bfcde0aac65c0faf7ceeeb55439987a78876d6a3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-ref.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-v.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/queue.jsonl": "b340f993dff712a9d47d4a4fe5bd0418d6826e5468319a98115de5cddd82b7ad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/ref-history.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/requests.csv": "53ea2ed9286427de07742f2ba22e2f8ca5f216c37e61c4b8d1506e0d90d6bbc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/state.npz": "770b7e29adbab3d29de20a77c9e3977f0da7d9cf2aaf68f346e1953683fb632c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/summary.json": "9dd57f49a08b8dc16aa76a73fad8d5beaca3a3a13c7b0b6bd3377df3b8ed22a5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/tick-state-hashes.jsonl": "4b03e6632b70d2dd056be18474c71c2ee4d202ffe212024e1001106875d5ea58",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/v-history.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/apl-drive.float32.npy": "694944eb4e7ede2146035bd4a3725a7ca84b59a2eb499ebab036998fc05c88b4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/apl-inhibition.float32.npy": "6652e316e26fdb7a1089fd8d586eecbb53d9643fa02c2f79722956fb70ce28d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/apl-state.float32.npy": "1b5d2c9959509781490fd5518682f448eaaafa0737d4de841ea0b816aeac0a11",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/g-history.float64.npy": "838543584e16f2f3954c16d9aa4bd7d196acbab1bff1b4702f5cc2525bf31161",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/preAPL-g.float64.npy": "b6b01f89be4922093b264f21bfcde0aac65c0faf7ceeeb55439987a78876d6a3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/preAPL-ref.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/preAPL-v.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/queue.jsonl": "b340f993dff712a9d47d4a4fe5bd0418d6826e5468319a98115de5cddd82b7ad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/ref-history.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/requests.csv": "53ea2ed9286427de07742f2ba22e2f8ca5f216c37e61c4b8d1506e0d90d6bbc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/state.npz": "770b7e29adbab3d29de20a77c9e3977f0da7d9cf2aaf68f346e1953683fb632c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/summary.json": "231a268dd0bf79e48d6c21b89ceb9133ff5798c6e15faed7198d7381c0705100",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/tick-state-hashes.jsonl": "4b03e6632b70d2dd056be18474c71c2ee4d202ffe212024e1001106875d5ea58",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1/v-history.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "natural_request",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-drive.float32.npy": "694944eb4e7ede2146035bd4a3725a7ca84b59a2eb499ebab036998fc05c88b4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-inhibition.float32.npy": "6652e316e26fdb7a1089fd8d586eecbb53d9643fa02c2f79722956fb70ce28d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/apl-state.float32.npy": "1b5d2c9959509781490fd5518682f448eaaafa0737d4de841ea0b816aeac0a11",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/g-history.float64.npy": "838543584e16f2f3954c16d9aa4bd7d196acbab1bff1b4702f5cc2525bf31161",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-g.float64.npy": "b6b01f89be4922093b264f21bfcde0aac65c0faf7ceeeb55439987a78876d6a3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-ref.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/preAPL-v.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/queue.jsonl": "b340f993dff712a9d47d4a4fe5bd0418d6826e5468319a98115de5cddd82b7ad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/ref-history.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/requests.csv": "53ea2ed9286427de07742f2ba22e2f8ca5f216c37e61c4b8d1506e0d90d6bbc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/state.npz": "770b7e29adbab3d29de20a77c9e3977f0da7d9cf2aaf68f346e1953683fb632c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/summary.json": "9dd57f49a08b8dc16aa76a73fad8d5beaca3a3a13c7b0b6bd3377df3b8ed22a5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/tick-state-hashes.jsonl": "4b03e6632b70d2dd056be18474c71c2ee4d202ffe212024e1001106875d5ea58",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0/v-history.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/apl-drive.float32.npy": "694944eb4e7ede2146035bd4a3725a7ca84b59a2eb499ebab036998fc05c88b4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/apl-inhibition.float32.npy": "6652e316e26fdb7a1089fd8d586eecbb53d9643fa02c2f79722956fb70ce28d2",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/apl-state.float32.npy": "1b5d2c9959509781490fd5518682f448eaaafa0737d4de841ea0b816aeac0a11",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/g-history.float64.npy": "838543584e16f2f3954c16d9aa4bd7d196acbab1bff1b4702f5cc2525bf31161",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/preAPL-g.float64.npy": "b6b01f89be4922093b264f21bfcde0aac65c0faf7ceeeb55439987a78876d6a3",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/preAPL-ref.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/preAPL-v.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/queue.jsonl": "b340f993dff712a9d47d4a4fe5bd0418d6826e5468319a98115de5cddd82b7ad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/ref-history.int32.npy": "26952260af393e7fb9295f711b6914038882d256529446883b5f2f0b09b82f18",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/requests.csv": "53ea2ed9286427de07742f2ba22e2f8ca5f216c37e61c4b8d1506e0d90d6bbc9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/state.npz": "770b7e29adbab3d29de20a77c9e3977f0da7d9cf2aaf68f346e1953683fb632c",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/summary.json": "2461eb55cd056af955371cb733b49b253962f870e673ac087835cf7083d869e5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/tick-state-hashes.jsonl": "4b03e6632b70d2dd056be18474c71c2ee4d202ffe212024e1001106875d5ea58",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2/v-history.float64.npy": "4d41f3fe83a23398815f7d4f65bb6634826bff4f29667c40e1740a856bacf1b9"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/natural_request-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "pn_pulse",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-drive.float32.npy": "d36ee1bc57cdb36c38fefe93da0493e17dabf899b02b2222468bd67bcad5edf5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-inhibition.float32.npy": "5d3c55e13884d2a86296e3826d4ebab1ca491458fee90cbb11972b0d895c76aa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-state.float32.npy": "b680c32977a56e9551cbebef9c2d14acca31e32f44c6109a7f0b2fa90a9bb63a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/g-history.float64.npy": "883f6482df737bf45b0914680e6d6c201735d7dc2a3fbdef1d352834875ed751",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-g.float64.npy": "be91ca1c4d7e5bc4d1d77ec7bd1c2aedcf284e4181f21d8cb3c24706348e5e8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-ref.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-v.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/queue.jsonl": "530b3632adf86c3d377d47ccca60ec7f4a98ea4e16b8fb6b835951990db8bfce",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/ref-history.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/requests.csv": "4add1e0a108ad83467de9335d4ea342b47ef565b1a6f6a586c65eb9b1774a176",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/state.npz": "cd3596d06b03fc4702dea4b528c7c704659ff9316e46bdf0b804b6a3ec3b9804",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/summary.json": "c4894ccbd533402b4347c778e60b7e100f9dca625e063075a38ae95f7a56fc4d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/tick-state-hashes.jsonl": "d1e9cc90604953dd31e085a841a8b813b7f43ef20ffcda5da5fbbf1d790c72fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/v-history.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/apl-drive.float32.npy": "d36ee1bc57cdb36c38fefe93da0493e17dabf899b02b2222468bd67bcad5edf5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/apl-inhibition.float32.npy": "5d3c55e13884d2a86296e3826d4ebab1ca491458fee90cbb11972b0d895c76aa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/apl-state.float32.npy": "b680c32977a56e9551cbebef9c2d14acca31e32f44c6109a7f0b2fa90a9bb63a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/g-history.float64.npy": "883f6482df737bf45b0914680e6d6c201735d7dc2a3fbdef1d352834875ed751",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/preAPL-g.float64.npy": "be91ca1c4d7e5bc4d1d77ec7bd1c2aedcf284e4181f21d8cb3c24706348e5e8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/preAPL-ref.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/preAPL-v.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/queue.jsonl": "530b3632adf86c3d377d47ccca60ec7f4a98ea4e16b8fb6b835951990db8bfce",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/ref-history.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/requests.csv": "4add1e0a108ad83467de9335d4ea342b47ef565b1a6f6a586c65eb9b1774a176",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/state.npz": "cd3596d06b03fc4702dea4b528c7c704659ff9316e46bdf0b804b6a3ec3b9804",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/summary.json": "da833f7be21b17a11cf7276aa16edb030e7f6630f74602b565280e85a1a1eb6f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/tick-state-hashes.jsonl": "d1e9cc90604953dd31e085a841a8b813b7f43ef20ffcda5da5fbbf1d790c72fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1/v-history.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 300,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "pn_pulse",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-drive.float32.npy": "d36ee1bc57cdb36c38fefe93da0493e17dabf899b02b2222468bd67bcad5edf5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-inhibition.float32.npy": "5d3c55e13884d2a86296e3826d4ebab1ca491458fee90cbb11972b0d895c76aa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/apl-state.float32.npy": "b680c32977a56e9551cbebef9c2d14acca31e32f44c6109a7f0b2fa90a9bb63a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/g-history.float64.npy": "883f6482df737bf45b0914680e6d6c201735d7dc2a3fbdef1d352834875ed751",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-g.float64.npy": "be91ca1c4d7e5bc4d1d77ec7bd1c2aedcf284e4181f21d8cb3c24706348e5e8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-ref.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/preAPL-v.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/queue.jsonl": "530b3632adf86c3d377d47ccca60ec7f4a98ea4e16b8fb6b835951990db8bfce",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/ref-history.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/requests.csv": "4add1e0a108ad83467de9335d4ea342b47ef565b1a6f6a586c65eb9b1774a176",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/state.npz": "cd3596d06b03fc4702dea4b528c7c704659ff9316e46bdf0b804b6a3ec3b9804",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/summary.json": "c4894ccbd533402b4347c778e60b7e100f9dca625e063075a38ae95f7a56fc4d",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/tick-state-hashes.jsonl": "d1e9cc90604953dd31e085a841a8b813b7f43ef20ffcda5da5fbbf1d790c72fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0/v-history.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/apl-drive.float32.npy": "d36ee1bc57cdb36c38fefe93da0493e17dabf899b02b2222468bd67bcad5edf5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/apl-inhibition.float32.npy": "5d3c55e13884d2a86296e3826d4ebab1ca491458fee90cbb11972b0d895c76aa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/apl-state.float32.npy": "b680c32977a56e9551cbebef9c2d14acca31e32f44c6109a7f0b2fa90a9bb63a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/g-history.float64.npy": "883f6482df737bf45b0914680e6d6c201735d7dc2a3fbdef1d352834875ed751",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/preAPL-g.float64.npy": "be91ca1c4d7e5bc4d1d77ec7bd1c2aedcf284e4181f21d8cb3c24706348e5e8f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/preAPL-ref.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/preAPL-v.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/queue.jsonl": "530b3632adf86c3d377d47ccca60ec7f4a98ea4e16b8fb6b835951990db8bfce",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/ref-history.int32.npy": "8822ef54d36d38cafad3f7f9f3d7c367824e56accab86cf2b2d4e6259b8a6e1f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/requests.csv": "4add1e0a108ad83467de9335d4ea342b47ef565b1a6f6a586c65eb9b1774a176",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/state.npz": "cd3596d06b03fc4702dea4b528c7c704659ff9316e46bdf0b804b6a3ec3b9804",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/summary.json": "59486c7a562c85805add859ba86e1064cc15c05329dc11442bc8834643338036",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/tick-state-hashes.jsonl": "d1e9cc90604953dd31e085a841a8b813b7f43ef20ffcda5da5fbbf1d790c72fd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2/v-history.float64.npy": "73d736804ba672f229669db83d9eb737cf73a6376686b1969f3b142ab4c05afe"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/pn_pulse-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 300,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "two_sources",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-drive.float32.npy": "656c1fb8a53ca1ed7c23b31f0b87a394ebca2af6e8be118d2dda6c972a5da180",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-inhibition.float32.npy": "c31530f2d09305d73bd37438ca1ed7e1d2b3cedfcfe6e4cced94279377b32081",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-state.float32.npy": "919e10a7ccb6c6ff4bd240dfe7a70f654df72068c254c63e67d8ffd6eea1ca03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/g-history.float64.npy": "b9378629d85a79968a366a61840cd7a9087c56b3b8c4f802b119abf1cfd81b30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-g.float64.npy": "3f495950e70bcc155e7b26060bdff21efb6d734e2e12c7ba9cc71f97be04c3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-ref.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-v.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/queue.jsonl": "180643201bea70bbb5d5127fcf5e7df0c198fad07a4c03d579afc79db007bf83",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/ref-history.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/requests.csv": "e60434045301b23a6e7da8907b14d0bd9e576b72ca90fae074237a8e6a20f053",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/state.npz": "ad50b02424e0dda0894e245442ae07ec02f4508ad4110795ebdd146067571975",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/summary.json": "773bcb4f7acdf4ac8863d9bc0c4fe5fc3604231e01ebb6e225c6ffbf0adcdee5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/tick-state-hashes.jsonl": "8251fe8617d284aba2ee8f764c2e0b4e990a9bc70fc65eac62fea97701187b4f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/v-history.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/apl-drive.float32.npy": "656c1fb8a53ca1ed7c23b31f0b87a394ebca2af6e8be118d2dda6c972a5da180",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/apl-inhibition.float32.npy": "c31530f2d09305d73bd37438ca1ed7e1d2b3cedfcfe6e4cced94279377b32081",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/apl-state.float32.npy": "919e10a7ccb6c6ff4bd240dfe7a70f654df72068c254c63e67d8ffd6eea1ca03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/g-history.float64.npy": "b9378629d85a79968a366a61840cd7a9087c56b3b8c4f802b119abf1cfd81b30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/preAPL-g.float64.npy": "3f495950e70bcc155e7b26060bdff21efb6d734e2e12c7ba9cc71f97be04c3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/preAPL-ref.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/preAPL-v.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/queue.jsonl": "180643201bea70bbb5d5127fcf5e7df0c198fad07a4c03d579afc79db007bf83",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/ref-history.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/requests.csv": "e60434045301b23a6e7da8907b14d0bd9e576b72ca90fae074237a8e6a20f053",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/state.npz": "ad50b02424e0dda0894e245442ae07ec02f4508ad4110795ebdd146067571975",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/summary.json": "a1a28fbb649cb17ff71f5358454f12d4e498fad3d3a81f567f69c2d0fa4c2dbd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/tick-state-hashes.jsonl": "8251fe8617d284aba2ee8f764c2e0b4e990a9bc70fc65eac62fea97701187b4f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1/v-history.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 300,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 13
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "two_sources",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-drive.float32.npy": "656c1fb8a53ca1ed7c23b31f0b87a394ebca2af6e8be118d2dda6c972a5da180",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-inhibition.float32.npy": "c31530f2d09305d73bd37438ca1ed7e1d2b3cedfcfe6e4cced94279377b32081",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/apl-state.float32.npy": "919e10a7ccb6c6ff4bd240dfe7a70f654df72068c254c63e67d8ffd6eea1ca03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/g-history.float64.npy": "b9378629d85a79968a366a61840cd7a9087c56b3b8c4f802b119abf1cfd81b30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-g.float64.npy": "3f495950e70bcc155e7b26060bdff21efb6d734e2e12c7ba9cc71f97be04c3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-ref.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/preAPL-v.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/queue.jsonl": "180643201bea70bbb5d5127fcf5e7df0c198fad07a4c03d579afc79db007bf83",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/ref-history.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/requests.csv": "e60434045301b23a6e7da8907b14d0bd9e576b72ca90fae074237a8e6a20f053",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/state.npz": "ad50b02424e0dda0894e245442ae07ec02f4508ad4110795ebdd146067571975",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/summary.json": "773bcb4f7acdf4ac8863d9bc0c4fe5fc3604231e01ebb6e225c6ffbf0adcdee5",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/tick-state-hashes.jsonl": "8251fe8617d284aba2ee8f764c2e0b4e990a9bc70fc65eac62fea97701187b4f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0/v-history.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/apl-drive.float32.npy": "656c1fb8a53ca1ed7c23b31f0b87a394ebca2af6e8be118d2dda6c972a5da180",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/apl-inhibition.float32.npy": "c31530f2d09305d73bd37438ca1ed7e1d2b3cedfcfe6e4cced94279377b32081",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/apl-state.float32.npy": "919e10a7ccb6c6ff4bd240dfe7a70f654df72068c254c63e67d8ffd6eea1ca03",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/g-history.float64.npy": "b9378629d85a79968a366a61840cd7a9087c56b3b8c4f802b119abf1cfd81b30",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/preAPL-g.float64.npy": "3f495950e70bcc155e7b26060bdff21efb6d734e2e12c7ba9cc71f97be04c3fa",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/preAPL-ref.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/preAPL-v.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/queue.jsonl": "180643201bea70bbb5d5127fcf5e7df0c198fad07a4c03d579afc79db007bf83",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/ref-history.int32.npy": "42dd80ca1b63bd07626fdde424defd77f6db7fefbc7f42c2aefa19b5ddf00ec1",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/requests.csv": "e60434045301b23a6e7da8907b14d0bd9e576b72ca90fae074237a8e6a20f053",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/state.npz": "ad50b02424e0dda0894e245442ae07ec02f4508ad4110795ebdd146067571975",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/summary.json": "2c5ce69312c8fb4605f1448f453db6ad2a0dc71c9cba69a3f9849156b2c060ae",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/tick-state-hashes.jsonl": "8251fe8617d284aba2ee8f764c2e0b4e990a9bc70fc65eac62fea97701187b4f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2/v-history.float64.npy": "f52791f25393bd315a69693b32044b12973dd63baaf3f468a9836ac9ea4dfcf4"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/two_sources-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 300,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 13
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "zero",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-ref.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/queue.jsonl": "c6ba176eb2004b9cf5e7df65a7989630c37c04b8933b5d79ab89febcc82f955a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/ref-history.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/requests.csv": "d2250de77a7723e0237f53b54038377b5502ccf3a549cc08f3344a1e924b99ac",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/state.npz": "acf8be16ad5ac4fab3a0fb96cd1b322b86cb0089f506f57a7d4a6043f4e18dff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/summary.json": "737fba9a39f9c30a2e4e337df01f1fc30ad482ca0357c8a3c8cd92170f2e35db",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/tick-state-hashes.jsonl": "e65f6ff485f0ac45811c9d9cea7183f89609dc5e2740fe183f0861cb3e1c6dad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/preAPL-ref.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/queue.jsonl": "c6ba176eb2004b9cf5e7df65a7989630c37c04b8933b5d79ab89febcc82f955a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/ref-history.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/requests.csv": "d2250de77a7723e0237f53b54038377b5502ccf3a549cc08f3344a1e924b99ac",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/state.npz": "acf8be16ad5ac4fab3a0fb96cd1b322b86cb0089f506f57a7d4a6043f4e18dff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/summary.json": "e06b218f12104283224564de2e7ff7f54f03809a345a122f57adf05e8c9608b9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/tick-state-hashes.jsonl": "e65f6ff485f0ac45811c9d9cea7183f89609dc5e2740fe183f0861cb3e1c6dad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r1",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
{
|
||||||
|
"case": "zero",
|
||||||
|
"checks": {
|
||||||
|
"apl.drive.bitwise_exact": true,
|
||||||
|
"apl.drive.finite": true,
|
||||||
|
"apl.drive.schema": true,
|
||||||
|
"apl.inhibition.bitwise_exact": true,
|
||||||
|
"apl.inhibition.finite": true,
|
||||||
|
"apl.inhibition.schema": true,
|
||||||
|
"apl.state.bitwise_exact": true,
|
||||||
|
"apl.state.finite": true,
|
||||||
|
"apl.state.schema": true,
|
||||||
|
"component.parsed_exact": true,
|
||||||
|
"first_gpu.apl_positive_drive": true,
|
||||||
|
"first_gpu.apl_positive_inhibition": true,
|
||||||
|
"first_gpu.apl_positive_state": true,
|
||||||
|
"first_gpu.apl_precision": true,
|
||||||
|
"first_gpu.case_name": true,
|
||||||
|
"first_gpu.component_summary_consistent": true,
|
||||||
|
"first_gpu.count_nonnegative_total": true,
|
||||||
|
"first_gpu.events_sorted_unique": true,
|
||||||
|
"first_gpu.history_final_g": true,
|
||||||
|
"first_gpu.history_final_ref": true,
|
||||||
|
"first_gpu.history_final_v": true,
|
||||||
|
"first_gpu.history_hashes_g": true,
|
||||||
|
"first_gpu.history_hashes_ref": true,
|
||||||
|
"first_gpu.history_hashes_v": true,
|
||||||
|
"first_gpu.history_mode": true,
|
||||||
|
"first_gpu.last_hash_g": true,
|
||||||
|
"first_gpu.last_hash_ref": true,
|
||||||
|
"first_gpu.last_hash_v": true,
|
||||||
|
"first_gpu.no_error_marker": true,
|
||||||
|
"first_gpu.ref_range": true,
|
||||||
|
"first_gpu.reported_events": true,
|
||||||
|
"first_gpu.request_summary": true,
|
||||||
|
"first_gpu.summary_complete": true,
|
||||||
|
"hashes.parsed_exact": true,
|
||||||
|
"histories.g.bitwise_exact": true,
|
||||||
|
"histories.g.finite": true,
|
||||||
|
"histories.g.schema": true,
|
||||||
|
"histories.ref.bitwise_exact": true,
|
||||||
|
"histories.ref.finite": true,
|
||||||
|
"histories.ref.schema": true,
|
||||||
|
"histories.v.bitwise_exact": true,
|
||||||
|
"histories.v.finite": true,
|
||||||
|
"histories.v.schema": true,
|
||||||
|
"pre.g.bitwise_exact": true,
|
||||||
|
"pre.g.finite": true,
|
||||||
|
"pre.g.schema": true,
|
||||||
|
"pre.ref.bitwise_exact": true,
|
||||||
|
"pre.ref.finite": true,
|
||||||
|
"pre.ref.schema": true,
|
||||||
|
"pre.v.bitwise_exact": true,
|
||||||
|
"pre.v.finite": true,
|
||||||
|
"pre.v.schema": true,
|
||||||
|
"queues.parsed_exact": true,
|
||||||
|
"requests.parsed_exact": true,
|
||||||
|
"second_gpu.apl_positive_drive": true,
|
||||||
|
"second_gpu.apl_positive_inhibition": true,
|
||||||
|
"second_gpu.apl_positive_state": true,
|
||||||
|
"second_gpu.apl_precision": true,
|
||||||
|
"second_gpu.case_name": true,
|
||||||
|
"second_gpu.component_summary_consistent": true,
|
||||||
|
"second_gpu.count_nonnegative_total": true,
|
||||||
|
"second_gpu.events_sorted_unique": true,
|
||||||
|
"second_gpu.history_final_g": true,
|
||||||
|
"second_gpu.history_final_ref": true,
|
||||||
|
"second_gpu.history_final_v": true,
|
||||||
|
"second_gpu.history_hashes_g": true,
|
||||||
|
"second_gpu.history_hashes_ref": true,
|
||||||
|
"second_gpu.history_hashes_v": true,
|
||||||
|
"second_gpu.history_mode": true,
|
||||||
|
"second_gpu.last_hash_g": true,
|
||||||
|
"second_gpu.last_hash_ref": true,
|
||||||
|
"second_gpu.last_hash_v": true,
|
||||||
|
"second_gpu.no_error_marker": true,
|
||||||
|
"second_gpu.ref_range": true,
|
||||||
|
"second_gpu.reported_events": true,
|
||||||
|
"second_gpu.request_summary": true,
|
||||||
|
"second_gpu.summary_complete": true,
|
||||||
|
"state.counts.bitwise_exact": true,
|
||||||
|
"state.counts.finite": true,
|
||||||
|
"state.counts.schema": true,
|
||||||
|
"state.g.bitwise_exact": true,
|
||||||
|
"state.g.finite": true,
|
||||||
|
"state.g.schema": true,
|
||||||
|
"state.neuron_idx.bitwise_exact": true,
|
||||||
|
"state.neuron_idx.finite": true,
|
||||||
|
"state.neuron_idx.schema": true,
|
||||||
|
"state.ref.bitwise_exact": true,
|
||||||
|
"state.ref.finite": true,
|
||||||
|
"state.ref.schema": true,
|
||||||
|
"state.step.bitwise_exact": true,
|
||||||
|
"state.step.finite": true,
|
||||||
|
"state.step.schema": true,
|
||||||
|
"state.v.bitwise_exact": true,
|
||||||
|
"state.v.finite": true,
|
||||||
|
"state.v.schema": true,
|
||||||
|
"summary.accepted_arriving_edges": true,
|
||||||
|
"summary.accepted_requests": true,
|
||||||
|
"summary.all_finite": true,
|
||||||
|
"summary.apl_fast_edges_zeroed": true,
|
||||||
|
"summary.apl_precision": true,
|
||||||
|
"summary.apl_schedule": true,
|
||||||
|
"summary.apl_si_conversion": true,
|
||||||
|
"summary.arriving_edges": true,
|
||||||
|
"summary.build": true,
|
||||||
|
"summary.case": true,
|
||||||
|
"summary.complete": true,
|
||||||
|
"summary.completed_ticks": true,
|
||||||
|
"summary.counts_match_sparse_events": true,
|
||||||
|
"summary.edges": true,
|
||||||
|
"summary.effective_weights_raw_sha256": true,
|
||||||
|
"summary.input_sha256": true,
|
||||||
|
"summary.kc_targets_present": true,
|
||||||
|
"summary.learning": true,
|
||||||
|
"summary.nodes": true,
|
||||||
|
"summary.pass_all": true,
|
||||||
|
"summary.precision": true,
|
||||||
|
"summary.record_history": true,
|
||||||
|
"summary.rejected_requests": true,
|
||||||
|
"summary.requested": true,
|
||||||
|
"summary.sealed_ae_backend_sha256": true,
|
||||||
|
"summary.state_units": true,
|
||||||
|
"summary.steps": true,
|
||||||
|
"summary.total_spikes": true
|
||||||
|
},
|
||||||
|
"differences": {},
|
||||||
|
"edges": 287,
|
||||||
|
"evidence_sha256": {
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-ref.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/queue.jsonl": "c6ba176eb2004b9cf5e7df65a7989630c37c04b8933b5d79ab89febcc82f955a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/ref-history.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/requests.csv": "d2250de77a7723e0237f53b54038377b5502ccf3a549cc08f3344a1e924b99ac",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/state.npz": "acf8be16ad5ac4fab3a0fb96cd1b322b86cb0089f506f57a7d4a6043f4e18dff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/summary.json": "737fba9a39f9c30a2e4e337df01f1fc30ad482ca0357c8a3c8cd92170f2e35db",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/tick-state-hashes.jsonl": "e65f6ff485f0ac45811c9d9cea7183f89609dc5e2740fe183f0861cb3e1c6dad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/apl-component.json": "f94b360033b4cb643c9774e7fa31c95a65c5571ca62b73072ee29b3af80121f9",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/apl-drive.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/apl-inhibition.float32.npy": "429a69417d057704b5a9364e5dc9968d7a690c83f43b096c9284be47835d4c9f",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/apl-state.float32.npy": "15fe3726f298f2ebcf01f147d8dbd995d41c1e9413138d858f341b8aa0df48bd",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/g-history.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/preAPL-g.float64.npy": "341065058e8e9fe15278f589bf59a527d9d42a0642176064405cc649c0f24086",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/preAPL-ref.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/preAPL-v.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/queue.jsonl": "c6ba176eb2004b9cf5e7df65a7989630c37c04b8933b5d79ab89febcc82f955a",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/ref-history.int32.npy": "452ae2ecf60cd4e28a42b9f1e764846d73789ed1a3e10d659eea5ed9926ccf56",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/requests.csv": "d2250de77a7723e0237f53b54038377b5502ccf3a549cc08f3344a1e924b99ac",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/state.npz": "acf8be16ad5ac4fab3a0fb96cd1b322b86cb0089f506f57a7d4a6043f4e18dff",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/summary.json": "9376c999edc2caf45eb6c845253400167b231b926244f87f6567d66f188f7108",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/tick-state-hashes.jsonl": "e65f6ff485f0ac45811c9d9cea7183f89609dc5e2740fe183f0861cb3e1c6dad",
|
||||||
|
"/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2/v-history.float64.npy": "e7fda85153afdfca62a8295976a28b2b83735cadaba9179a3922095c02d3c9b6"
|
||||||
|
},
|
||||||
|
"explicit_exclusions": [
|
||||||
|
"wall_seconds",
|
||||||
|
"diagnostic_simulation_seconds",
|
||||||
|
"build_or_cache_seconds",
|
||||||
|
"peak_allocated_vram_bytes",
|
||||||
|
"peak_reserved_vram_bytes"
|
||||||
|
],
|
||||||
|
"failed_checks": [],
|
||||||
|
"first": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r0",
|
||||||
|
"kind": "fresh-GPU-run exact repeat comparison",
|
||||||
|
"nodes": 44,
|
||||||
|
"pass_all": true,
|
||||||
|
"record_history": true,
|
||||||
|
"scope": "Scientific outputs, recording integrity and input hashes; independent case/graph audit belongs to compare()",
|
||||||
|
"second": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/gpu/zero-r2",
|
||||||
|
"signed_zero_included": true,
|
||||||
|
"steps": 100,
|
||||||
|
"timing_fields_compared": false,
|
||||||
|
"tolerance": null,
|
||||||
|
"total_spikes": 0
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "apl_only",
|
||||||
|
"kind": "fixture",
|
||||||
|
"steps": 100,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 10.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": true,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "arrival_collision",
|
||||||
|
"kind": "fixture",
|
||||||
|
"steps": 120,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 12.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/fixtures",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": true,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-00-s51101",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "OMSUIQOIVADKIM-RXMQYKEDSA-N",
|
||||||
|
"odor_name": "ethyl (R)-(-)-3-hydroxybutanoate",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51101,
|
||||||
|
"odor_index": 0,
|
||||||
|
"expected_external_events": 102.24431762695312,
|
||||||
|
"target_count": 48,
|
||||||
|
"rate_sum_hz": 1022.4431762695312
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-00-s51102",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "OMSUIQOIVADKIM-RXMQYKEDSA-N",
|
||||||
|
"odor_name": "ethyl (R)-(-)-3-hydroxybutanoate",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51102,
|
||||||
|
"odor_index": 0,
|
||||||
|
"expected_external_events": 102.24431762695312,
|
||||||
|
"target_count": 48,
|
||||||
|
"rate_sum_hz": 1022.4431762695312
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-00-s51103",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "OMSUIQOIVADKIM-RXMQYKEDSA-N",
|
||||||
|
"odor_name": "ethyl (R)-(-)-3-hydroxybutanoate",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51103,
|
||||||
|
"odor_index": 0,
|
||||||
|
"expected_external_events": 102.24431762695312,
|
||||||
|
"target_count": 48,
|
||||||
|
"rate_sum_hz": 1022.4431762695312
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-00-s51104",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "OMSUIQOIVADKIM-RXMQYKEDSA-N",
|
||||||
|
"odor_name": "ethyl (R)-(-)-3-hydroxybutanoate",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51104,
|
||||||
|
"odor_index": 0,
|
||||||
|
"expected_external_events": 102.24431762695312,
|
||||||
|
"target_count": 48,
|
||||||
|
"rate_sum_hz": 1022.4431762695312
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-00-s51105",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "OMSUIQOIVADKIM-RXMQYKEDSA-N",
|
||||||
|
"odor_name": "ethyl (R)-(-)-3-hydroxybutanoate",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51105,
|
||||||
|
"odor_index": 0,
|
||||||
|
"expected_external_events": 102.24431762695312,
|
||||||
|
"target_count": 48,
|
||||||
|
"rate_sum_hz": 1022.4431762695312
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-01-s51101",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"odor_name": "3-penten-2-one",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51101,
|
||||||
|
"odor_index": 1,
|
||||||
|
"expected_external_events": 102.2443115234375,
|
||||||
|
"target_count": 55,
|
||||||
|
"rate_sum_hz": 1022.443115234375
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-01-s51102",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"odor_name": "3-penten-2-one",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51102,
|
||||||
|
"odor_index": 1,
|
||||||
|
"expected_external_events": 102.2443115234375,
|
||||||
|
"target_count": 55,
|
||||||
|
"rate_sum_hz": 1022.443115234375
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-01-s51103",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"odor_name": "3-penten-2-one",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51103,
|
||||||
|
"odor_index": 1,
|
||||||
|
"expected_external_events": 102.2443115234375,
|
||||||
|
"target_count": 55,
|
||||||
|
"rate_sum_hz": 1022.443115234375
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-01-s51104",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"odor_name": "3-penten-2-one",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51104,
|
||||||
|
"odor_index": 1,
|
||||||
|
"expected_external_events": 102.2443115234375,
|
||||||
|
"target_count": 55,
|
||||||
|
"rate_sum_hz": 1022.443115234375
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-01-s51105",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "LABTWGUMFABVFG-ARJAWSKDSA-N",
|
||||||
|
"odor_name": "3-penten-2-one",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51105,
|
||||||
|
"odor_index": 1,
|
||||||
|
"expected_external_events": 102.2443115234375,
|
||||||
|
"target_count": 55,
|
||||||
|
"rate_sum_hz": 1022.443115234375
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-02-s51101",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "QNVRIHYSUZMSGM-ZCFIWIBFSA-N",
|
||||||
|
"odor_name": "(2R)-hexan-2-ol",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51101,
|
||||||
|
"odor_index": 2,
|
||||||
|
"expected_external_events": 102.24430541992187,
|
||||||
|
"target_count": 33,
|
||||||
|
"rate_sum_hz": 1022.4430541992188
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-02-s51102",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "QNVRIHYSUZMSGM-ZCFIWIBFSA-N",
|
||||||
|
"odor_name": "(2R)-hexan-2-ol",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51102,
|
||||||
|
"odor_index": 2,
|
||||||
|
"expected_external_events": 102.24430541992187,
|
||||||
|
"target_count": 33,
|
||||||
|
"rate_sum_hz": 1022.4430541992188
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-02-s51103",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "QNVRIHYSUZMSGM-ZCFIWIBFSA-N",
|
||||||
|
"odor_name": "(2R)-hexan-2-ol",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51103,
|
||||||
|
"odor_index": 2,
|
||||||
|
"expected_external_events": 102.24430541992187,
|
||||||
|
"target_count": 33,
|
||||||
|
"rate_sum_hz": 1022.4430541992188
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-02-s51104",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "QNVRIHYSUZMSGM-ZCFIWIBFSA-N",
|
||||||
|
"odor_name": "(2R)-hexan-2-ol",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51104,
|
||||||
|
"odor_index": 2,
|
||||||
|
"expected_external_events": 102.24430541992187,
|
||||||
|
"target_count": 33,
|
||||||
|
"rate_sum_hz": 1022.4430541992188
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-02-s51105",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "QNVRIHYSUZMSGM-ZCFIWIBFSA-N",
|
||||||
|
"odor_name": "(2R)-hexan-2-ol",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51105,
|
||||||
|
"odor_index": 2,
|
||||||
|
"expected_external_events": 102.24430541992187,
|
||||||
|
"target_count": 33,
|
||||||
|
"rate_sum_hz": 1022.4430541992188
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-03-s51101",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"odor_name": "gamma-propyl-gamma-butyrolactone",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51101,
|
||||||
|
"odor_index": 3,
|
||||||
|
"expected_external_events": 102.24432373046875,
|
||||||
|
"target_count": 44,
|
||||||
|
"rate_sum_hz": 1022.4432373046875
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-03-s51102",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"odor_name": "gamma-propyl-gamma-butyrolactone",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51102,
|
||||||
|
"odor_index": 3,
|
||||||
|
"expected_external_events": 102.24432373046875,
|
||||||
|
"target_count": 44,
|
||||||
|
"rate_sum_hz": 1022.4432373046875
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-03-s51103",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"odor_name": "gamma-propyl-gamma-butyrolactone",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51103,
|
||||||
|
"odor_index": 3,
|
||||||
|
"expected_external_events": 102.24432373046875,
|
||||||
|
"target_count": 44,
|
||||||
|
"rate_sum_hz": 1022.4432373046875
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-03-s51104",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"odor_name": "gamma-propyl-gamma-butyrolactone",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51104,
|
||||||
|
"odor_index": 3,
|
||||||
|
"expected_external_events": 102.24432373046875,
|
||||||
|
"target_count": 44,
|
||||||
|
"rate_sum_hz": 1022.4432373046875
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-03-s51105",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "VLSVVMPLPMNWBH-UHFFFAOYSA-N",
|
||||||
|
"odor_name": "gamma-propyl-gamma-butyrolactone",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51105,
|
||||||
|
"odor_index": 3,
|
||||||
|
"expected_external_events": 102.24432373046875,
|
||||||
|
"target_count": 44,
|
||||||
|
"rate_sum_hz": 1022.4432373046875
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "cal-matched_energy-04-s51101",
|
||||||
|
"kind": "calibration",
|
||||||
|
"steps": 1000,
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"duration_ms": 100.0,
|
||||||
|
"model": {
|
||||||
|
"dt_ms": 0.1,
|
||||||
|
"membrane_tau_ms": 20.0,
|
||||||
|
"synaptic_tau_ms": 5.0,
|
||||||
|
"refractory_ms": 2.2,
|
||||||
|
"resting_potential_mv": -52.0,
|
||||||
|
"reset_potential_mv": -52.0,
|
||||||
|
"threshold_mv": -45.0,
|
||||||
|
"synaptic_delay_ms": 1.8,
|
||||||
|
"w_syn_mv_per_anatomical_synapse": 0.275
|
||||||
|
},
|
||||||
|
"graph_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/graphs/full",
|
||||||
|
"apl_bundle_dir": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2/apl-bundle",
|
||||||
|
"apl": {
|
||||||
|
"tau_ms": 20.0,
|
||||||
|
"gain": 0.01,
|
||||||
|
"normalization": 1.0
|
||||||
|
},
|
||||||
|
"record_history": false,
|
||||||
|
"coefficients_path": "/data/digital-drosophila/experiments/phase4af-author-fullgraph/oracle/no_input/coefficients.json",
|
||||||
|
"science_python": "/data/digital-drosophila/models/male-cns-lif/.venv/bin/python",
|
||||||
|
"legacy_apl_worker": "/data/digital-drosophila/models/male-cns-lif/author-apl-lab-v2/legacy_apl_worker.py",
|
||||||
|
"budget_root": "/data/digital-drosophila/experiments/phase4ag-author-apl-r2",
|
||||||
|
"output_budget_bytes": 16106127360,
|
||||||
|
"precision": "float64",
|
||||||
|
"apl_precision": "float32",
|
||||||
|
"training": false,
|
||||||
|
"odor_id": "XHIUFYZDQBSEMF-UHFFFAOYSA-N",
|
||||||
|
"odor_name": "2-methyl butyl acetate",
|
||||||
|
"mode": "matched_energy",
|
||||||
|
"seed": 51101,
|
||||||
|
"odor_index": 4,
|
||||||
|
"expected_external_events": 102.24432373046875,
|
||||||
|
"target_count": 48,
|
||||||
|
"rate_sum_hz": 1022.4432373046875
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user