2017-09-18 4 views
2

私はsympyを使って微分方程式のシステムを扱っています。私は式を象徴的に書いて、autowrapを使ってcythonでそれらをコンパイルし、その結果の関数をscipy ODEソルバに渡します。これを行うことの大きな利点の1つは、sympy jacobian関数を使用して象徴的にジャコビアを解くことができ、それをコンパイルしてODEソルバーにも渡せることです。大規模な行列を使ったsympyコンパイル関数

これは約30変数のシステムでうまく機能しています。最近、私は150の変数でそれをやろうとしましたが、ジャコビア関数をコンパイルするときにメモリが足りなくなったということが起こりました。これは、anacondaとPython用のMicrosoft Visual C++ 14ツールを備えたWindows上にあります。基本的に22000要素のベクトルであるジャコビアンのコンパイル中に、リンクステップ中のメモリ使用量は、最終的にクラッシュする前に約7GB(私の8GBノートパソコンで)になりました。

メモリを増やすマシンを試してみる前に、誰か提案がありますか?他のオペレーティングシステムや他のCコンパイラが状況を改善する可能性がありますか?

私はたくさんの人がこのタイプの仕事をしていることを知っています。答えがあれば、コミュニティの良い塊には有益でしょう。

編集:ジョナサンのコメントのいくつかに応答:

はい、私はこれはN^2の問題であることを十分に認識です。ヤコビ行列はすべての偏微分の行列です。したがって、サイズはN^2になります。このスケーリングの周りには本当の方法はありません。しかし、22000要素の配列は、実行時にメモリの問題を引き起こすレベルにはほとんど達していません。コンパイル時にのみ問題があります。

基本的に、これに対処できる3つのレベルがあります。

1)ジャコビアなしでODEの問題を解決するか、何とかヤコビ行列を分割して150x150の行列を持たないようにします。それは非常に根本に対処するが、確かに私ができることを制限し、私はまだヤコビの関数をコンパイルすることは不可能だと確信していない

2)方法について何かを変更するsympyは、それを複数のチャンクに分割し、中間表現にもっと多くの関数を使い、何らかの形で.cファイルを小さくします。 sympyの経験が豊富な人は、これに関するいくつかのアイデアを持っているかもしれません。

3)Cのコンパイル方法を変更して、メモリが少なくて済むようにします。

#3(literal referencing of large array -- compiler out of memory)の周りに別の質問を掲載することで、私は別のユーザーが回答することになると思いました。それは実際に起こったことです。おそらく、#3への答えは「できません」ですが、それも有益な情報です。

+0

私は同じ制限に縛られているので、私はこの質問を2番目にしなければなりません。しかし、私にとっては、まっすぐなクラッシュではなく、「致命的なエラーC1002:コンパイラーがパス2のヒープスペースを使いません」というメッセージが表示されます。同僚のマシン上のubuntu + gccコンパイラの簡単な試行では残念なことにこの問題は解決されませんでした。他に何も助けなければ、ヤコビ行列のいくつかのサブ行列で 'autowrap'を使ってこの問題を回避することができ、Pythonで関数を定義して、それらの部分を再び組み立てることができます。それはもちろん回避策であり、理想からは遠いです。 – DavidP

+0

はい、申し訳ありませんが、私は「クラッシュ」をややゆるやかに使っていました。私は同じか、あるいは似たようなエラーを受けます。 –

+0

次の質問[メモリからの大規模配列コンパイラのリテラル参照](https://stackoverflow.com/questions/46380587)に注意してください。それは現在、これの複製として閉じられています。重複ステータスが変更された場合は、このコメントに「不要になった」フラグを付けてください。 –

答えて

0

http://www.sympy.org/scipy-2017-codegen-tutorial/に投稿された多くの例に続いて、私はこれをコンパイルすることができました。

重要なことは でした。autowrapを使用する代わりに、Cコードを直接制御して書きます。とりわけ、引数リストを展開するのではなくベクトルとして渡すことができます。これはいくつかの努力を払って(distutilsなどでコンパイラフラグを設定するなど)、最終的にうまくいきました。例として上にリンクされたコースからのレポを持つことは多くの助けになりました。

2)共通部分式消去(sympy.cse)を使用して、ジャコビア要素の式のサイズを大幅に縮小します。

(1)それだけではあまり効果がありませんでしたが(私はそれを使用してより小さなモデルのパフォーマンスを大幅に向上させることができました)。コードは元の300 MBではなく200 MBでした。しかし、それを(2)(cse)と組み合わせると、(14000の一時変数にもかかわらず)貧弱な1.7 MBにまで減らすことができました。

cseは私のノートパソコンで約20-30分かかります。その後、すぐにコンパイルされます。

関連する問題