【发布时间】:2018-02-27 01:35:30
【问题描述】:
我一直在使用sympy 处理微分方程组。我象征性地编写方程,使用autowrap 通过 cython 编译它们,然后将结果函数传递给 scipy ODE 求解器。这样做的主要好处之一是我可以使用 sympy jacobian 函数象征性地求解雅可比,对其进行编译,并将其传递给 ODE 求解器。
这对于大约 30 个变量的系统非常有效。最近我尝试用 150 个变量来做,结果是我在编译 jacobian 函数时内存不足。这是在带有 anaconda 和用于 python 的 Microsoft Visual C++ 14 工具的 Windows 上。基本上,在 jacobian(现在是 22000 个元素的向量)的编译过程中,链接步骤期间的内存使用量上升到大约 7GB(在我的 8GB 笔记本电脑上),然后最终崩溃。
在我去尝试内存更大的机器之前,有人有什么建议吗?其他操作系统或其他 C 编译器是否可能会改善这种情况?
我知道很多人都在做这种类型的工作,所以如果有答案,这将对社区的大部分人有益。
编辑:对乔纳森的一些 cmets 的回应:
是的,我完全知道这是一个 N^2 问题。雅可比是所有偏导数的矩阵,因此它的大小为 N^2。这种缩放没有真正的方法。但是,一个 22000 个元素的数组几乎不会在运行时造成内存问题——我只是在编译期间遇到问题。
基本上我们可以在三个层次上解决这个问题。
1) 在没有 jacobian 的情况下解决 ODE 问题,或者以某种方式将 jacobian 拆分为没有 150x150 矩阵。这将解决最根本的问题,但它肯定会限制我能做的事情,而且我还不相信编译 jacobian 函数是不可能的
2) 更改 sympy 自动生成 C 代码的方式,将其拆分为多个块,为中间表达式使用更多函数,以某种方式使 .c 文件更小。有更多同情经验的人可能对此有一些想法。
3) 更改 C 的编译方式,从而减少所需的内存。
我认为通过发布一个更针对 #3 (literal referencing of large array -- compiler out of memory) 的单独问题,我会得到不同的听众回答。事实上,这正是发生的事情。或许 #3 的答案是“你不能”,但这也是有用的信息。
【问题讨论】:
-
我必须支持这个问题,因为我受到同样的限制;但是,对我来说,我收到消息“致命错误 C1002:编译器在第 2 次过程中堆空间不足”,而不是直接崩溃。不幸的是,在同事的机器上快速尝试 ubuntu + gcc-compiler 并没有解决问题。如果没有其他帮助,可以通过在雅可比行列式的几个子矩阵上使用“自动换行”来解决这个问题,并在 python 中定义一个函数来将这些部分重新组合在一起。这当然是一种解决方法,但远非理想。
-
是的,对不起,我使用“crash”有点松散。我得到相同或类似的错误。
-
注意后续问题Literal referencing of large array — compiler out of memory。这目前已作为副本关闭。如果重复状态已更改,请将此评论标记为“不再需要”。
-
如另一个问题中所述,您的问题似乎是缩放 O(N²)。随着问题规模的扩大,无论您拥有多少内存,您都将迅速耗尽内存。您需要找到一种方法来避免解决方案代码的二次增长。