# 势能面拟合与PINN神经网络专用框架 by CPP **Repository Path**: hao-yiping/Pikachu ## Basic Information - **Project Name**: 势能面拟合与PINN神经网络专用框架 by CPP - **Description**: 为计算化学领域的某些任务开发的神经网络训练和推理框架,主要服务于势能面拟合以及PINN任务。 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2025-03-17 - **Last Updated**: 2026-09-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Pikachu2 一个面向大型符号算子、高阶导数和势能面模型的 C++ 混合自动微分研究原型。 > **项目状态:重启中的未完成原型。** > > 前端、张量计算图和最困难的符号自动微分中端已经有较完整的实现,符号核也已能输出独立的静态 C++11 函数;但完整张量图后端、系统性的图优化和大规模验证仍未完成。它目前不是可替代 PyTorch/JAX 的生产框架,更适合作为“两层自动微分与符号核融合”的实验实现和可执行设计档案。 ## 项目要解决什么问题 Pikachu2 最初服务于 PIP NN PES(使用置换不变多项式的神经网络势能面)训练。较大体系的 PIP 可能包含十万到百万量级的单项式:它在数学上是一个庞大的标量符号程序,而不是普通深度学习框架最擅长处理的一串中等粒度张量算子。 如果把每一次标量加法、乘法和幂都展开成外层计算图节点,图规模、调度和中间量会迅速膨胀;如果把整段 PIP 封装成不可见的外部算子,框架又无法继续对它自动微分。本项目因此采用两层表示: - **外层张量计算图**描述网络、张量形状、指标、参数以及算子依赖; - **内层符号表达式图**描述一个非线性算子内部可能很大的标量程序,并在这一层进行微分、化简和 lowering。 PIP 是最初的典型用例,但不是功能边界。更一般的目标是: > 让任意“足够大、值得整体处理”的标量表达式成为张量图中的可微融合单元。 短表达式可以直接留在普通张量图中;大型表达式则保留为一个符号超级节点。其内部中间量不会被强制物化成大量外层张量,微分后的表达式仍是可化简、可继续微分、可静态生成代码的符号程序。换言之,这种分层在表示层面自然完成了一部分算子融合。 ## 为什么需要前向和反向两种微分 在势能面模型中,力来自能量对原子坐标的导数: ```text E(R, θ) ──∂/∂R──▶ F(R, θ) = -∂E/∂R │ ▼ force loss │ ∂/∂θ ▼ 坐标—参数混合二阶导数 ``` 一旦使用力标签训练,再对模型参数求梯度,实际就需要混合高阶导数。因此,Pikachu2 没有把某一种微分模式固定为唯一主路径,而是让前向和反向微分都生成仍可参与后续图变换的表示,用于组合 Jacobian、梯度和 Hessian-vector product 等对象。 “前向/反向平等”如今并非框架独有卖点;这里真正值得保留的是:**符号层生成大型算子的局部导数,张量层组合整个模型的 JVP/VJP,并让导数跨越两层边界后仍然可微。** ## 架构概览 ```text 自定义 DSL / 参数文件 │ ▼ parser + context │ ▼ NetWork 张量计算图 ├── 线性张量节点:按指标规则传播导数 └── MonoNonlinear / DiNonlinear │ ▼ Expres 标量符号 DAG │ │ forward AD backward AD └─────┬─────┘ ▼ Simplify pass 管线 │ ▼ VISA1 顺序标量程序 │ ▼ 符号核 C++ 后端(已实现) 全张量图后端(待补齐) ``` 主要组件: - `Expres`:当前主要的标量符号 DAG,支持输入叶、参数叶、常量和少量初等函数; - `MonoFunc` / `DiFunc`:把单输入或“普通输入 + 参数”的表达式组织成可重复微分的符号核; - `NetWork` 与各类 `Node`:管理外层张量图和 forward、backward、Jacobian、Hv 等图变换; - dummy、repeated、new index:表达缩并、保留维度以及微分新增维度的内部指标规则; - `VISA1`:把符号 DAG lowering 为加载、运算、函数调用和存储组成的顺序虚拟指令,可解释执行,也可作为静态代码生成的语义入口。 ## 当前完成度 | 能力 | 状态 | | --- | --- | | 自定义 DSL、上下文与张量图构造 | 已有实现,但不是未来最值得保留的部分 | | 标量符号 DAG | 已实现 | | 输入/参数分量的前向符号微分 | 已实现,基础路径已有回归 | | 标量输出的反向符号微分 | 已实现,已修复一批确定性错误 | | 反复微分形成高阶表达式 | 结构上可行,组合正确性尚未系统验证 | | 基础化简、常量折叠、DCE 与部分 CSE | 已实现;pass 规格和浮点语义仍需整理 | | VISA1 lowering 与解释执行 | 已实现,可作为参考语义 | | 张量图与符号核的微分衔接 | 已实现主要结构,缺少完整纵向数值验证 | | 符号核静态 C++ 后端 | 已实现,可生成不依赖 Pikachu2 的 C++11 函数 | | 完整张量图 C++ 后端 | 只有旧骨架 | | CUDA/JAX 后端 | 未实现 | | 十万至百万单项式 PIP 基准 | 未建立 | ## 重启记录:应该保留什么,舍弃什么 这是一个物理化学背景开发者独立完成的大型研究型项目。它同时手写了容器、字符串与字典、图结构、词法语法分析、自定义 DSL、张量描述、符号代数、自动微分、运行时和后端骨架。这样的工程宽度使核心问题之外的维护成本持续增长,也造成裸指针所有权、隐含不变量、代际接口并存、构建可移植性弱和测试不足等问题。 这段历史并不意味着核心思路没有价值。相反,它说明项目属于“研究问题选得对,但工程边界铺得太大”: - 值得保留的是符号核与张量图的两层 IR、跨层微分语义以及静态代码生成边界; - 不值得原样延续的是自定义通用基础设施、三代并存的表达式接口和缺少规格的优化 pass; - 如果将来迁移到 Python,应让 Python 和成熟容器承担前端与图管理,而不是机械翻译旧类层次; - 在迁移前,现有 C++ 最适合先补成一个能执行的语义参考,避免“重写”和“纠正数学语义”同时发生。 2026-09 的首轮重启工作修复了一批构建、张量指标、反向微分、`DiFunc`、常量语义和 VISA1 寄存器问题,并增加 Test063 定向回归。随后新增的 Test064 与独立编译调用器验证了符号核静态 C++ 后端。它们建立的是一个最小可信基线,而不是对整个框架正确性的背书。 ## 建议的重启路线 1. **稳定现有 C++ 中端。** 为每个原语、图结构和关键 pass 建立 primal/JVP/VJP/高阶导数数值对照。 2. **扩展最小静态 C++ 后端。** `Expres/VISA1` 到独立 C++11 函数已经完成;下一步用朴素循环和临时缓冲连接外层张量图。 3. **跑通一条真实纵向链路。** 验证能量、守恒力、力损失以及力损失对参数的混合二阶导数。 4. **最后迁移外围。** 再考虑 Python 前端、成熟图容器、JAX 对照以及 C++/CUDA/JAX 多后端。 第一阶段不追求恢复完整 DSL、通用动态图、训练器、CUDA 和激进优化。合理的成功标准是:用尽可能小的代码证明大型符号核能够嵌入张量图、跨层自动微分能够正确组合,并输出独立的静态程序。 ## 构建与运行 当前构建脚本面向 Linux/WSL,需要 Bash、GNU Make 和支持 C++11 的 G++。默认构建不要求 MKL。 从项目根目录执行干净构建: ```bash bash ./install.sh -c -o 0 ``` 生成的测试程序位于 `test/test.exe`。运行已有默认入口: ```bash bash ./run.sh ``` 运行首轮重启新增的符号微分回归: ```bash ./test/test.exe ./parameter/symbolic_regression.txt ``` 成功时会输出: ```text Test063: symbolic differentiation regressions passed. ``` 生成并独立编译符号 C++ 后端的命令见[符号 C++ 后端说明](docs/symbolic-cpp-backend.md)。 `install.sh` 的 `-o 0|1|2|3` 控制优化等级,`-g` 添加调试信息,`-c` 在构建前清理,`-C` 只清理。更多说明见下方文档。 ## 文档导航 | 文档 | 内容 | | --- | --- | | [重启说明](docs/restart-notes.md) | 项目历史、价值判断、工程问题和重启边界 | | [符号微分中端设计说明](docs/symbolic-differentiation.md) | 表达式 IR、前向/反向微分、优化 pass、VISA1 和验证建议 | | [符号 C++ 后端](docs/symbolic-cpp-backend.md) | 代码生成接口、ABI、lowering 选择、验证方法和当前边界 | | [首轮修复记录](docs/log/2026-09-09-restart-fixes.md) | 已修复问题、回归范围、验证结果和剩余风险 | | [符号 C++ 后端实现记录](docs/log/2026-09-10-symbolic-cpp-backend.md) | 后端实现、测试中发现的 MiniReg bug 和独立编译结果 | | [张量图 C++ 后端](docs/tensor-graph-cpp-backend.md) | 静态张量图 lowering、生成 ABI、支持节点和当前优化边界 | | [张量图 C++ 后端实现记录](docs/log/2026-09-10-tensor-graph-cpp-backend.md) | 完整张量后端、DSL 修复和数值验证结果 | | [网络与张量图](docs/network.md) | 网络节点、指标和计算图设计的旧版详细说明 | | [安装脚本](docs/install.md) | `install.sh` 参数 | | [运行脚本](docs/run.md) | `run.sh` 参数 | ## 已知限制 - `pow` 的指数导数对底数定义域有隐含假设,负底数和常整数指数仍需专门处理; - `0*x`、`x/x` 等实代数化简与含 NaN/Inf 的严格 IEEE 语义并不完全一致; - 多维输入与多维参数交错的高阶微分缺少完整测试矩阵; - `manifold::DiForward` 尚未实现; - 完整张量图 C++ 后端、CUDA 后端和成熟内存规划尚未完成;当前 C++ 生成器只覆盖符号核; - 尚不能用大型 PIP 的编译时间、峰值内存和运行性能数据证明可扩展性。 ## 项目定位 Pikachu2 不再以“成为另一套通用神经网络框架”为目标。它更现实也更有价值的定位是: > 一个研究大型符号表达式如何作为张量图中可微融合算子,并支持高阶混合导数与静态代码生成的实验原型。 项目采用 MIT License。历史联系邮箱:`hyper@dicp.ac.cn`。