Sympy用大型矩阵编译功能



我一直在使用 sympy与微分方程系统一起使用。我象征性地编写方程式,使用autowrap通过Cython编译它们,然后将结果函数传递给Scipy Ode求解器。这样做的主要好处之一是,我可以使用sympy jacobian函数象征性地解决雅各布,并将其编译为ODE求解器。

这对大约30个变量的系统非常有用。最近,我尝试使用150个变量进行操作,而发生的事情是在编译Jacobian功能时用完了记忆。这是在Windows上使用Anaconda和Microsoft Visual C 14 python的工具。基本上,在雅各比式的汇编(现在是22000个元素的矢量)期间,链接步骤期间的内存使用量达到约7GB(在我的8GB笔记本电脑上),然后最终崩溃。

有人去尝试使用更多内存的计算机之前,有人有一些建议吗?其他操作系统或其他C编译器是否可能改善情况?

我知道很多人从事这种类型的工作,因此,如果有答案,它将对社区的很大一部分有益。

编辑:响应乔纳森的一些评论:

是的,我完全知道这是一个n^2问题。Jacobian是所有部分衍生物的矩阵,因此它的尺寸为n^2。这个缩放没有真正的方法。但是,一个22000个元素数组不在运行时会造成内存问题的级别 - 我只在编译过程中遇到问题。

基本上有三个级别我们可以解决这个问题。

1)在没有Jacobian的情况下解决了ODE问题,或以某种方式将Jacobian分开以没有150x150矩阵。这将解决根源,但这肯定会限制我可以做的事情,而且我还不相信不可能编译Jacobian功能

是不可能的

2)更改有关sympy自动生成C代码的方式,将其分为多个块,使用更多功能进行中间表达式,以某种方式使.c文件较小。拥有更多Synspy经验的人可能对此有一些想法。

3)更改有关C编译C的方式,因此需要更少的内存。

我认为,通过发布一个围绕#3的单独问题(大型数组的字面引用 - 编译器中的编译器),我会得到不同的受众回答。实际上,这正是发生的事情。也许#3的答案是"您不能",但这也是有用的信息。

遵循许多示例发布在http://www.sympy.org/scipy-2017-codegen-tutorial/我能够将其汇编为compile。

关键是1)而不是使用autowrap,而是直接编写C代码,以更多地控制它。除其他事项外,这允许将参数列表作为向量传递,而不是将其扩展。这花了一些努力来开始工作(通过驱动器等建立编译器标志等),但最终效果很好。将上面链接的课程中的存储库提供了很多帮助。

2)使用常见的子表达消除(sympy.cse)大大减少雅各布元素表达式的大小。

在这种情况下,

(1)本身并没有做太多帮助(尽管我能够使用它来大大提高较小型号的性能)。代码仍然为200 MB,而不是原始的300 MB。但是将其与(2)(cse)结合使用,我能够将其降低到1.7 MB(尽管有14000个临时变量)。

cse在我的笔记本电脑上大约需要20-30分钟。之后,它很快编译。

最新更新