(方法)より高速に実行されるシミュレーションを作成しますか?


16

私はすべての割り当てをCFDで行うためのプログラミング言語としてpythonを使い始めました。プログラミングの経験はほとんどありません。私は機械工学の経験があり、航空宇宙工学の高等教育を追求しています。

CFDの計算面は、方程式を操作したり、数学を実行したりするよりも面倒になります。

プログラムの実行を高速化する一般的なガイドラインは何ですか?物事を並行して行うコツは何ですか?より高速に実行されるコードを記述する方法は?

上記の質問に答えるリソース(私のような素人にとって理解しやすい)はどこで入手できますか?



@ダン、私はそうは思わない。私は、新人のプログラミング戦術を理解するのに役立つ「あらゆる」可能なリソースを求めています。特定の要件や条件はありません。より具体的には、コードをよりエレガントにするのに役立つリソースを求めています。
-Subodh

あなたはPythonで修正されていますか、それともC ++を検討しますか?この場合、2つのことをお勧めします。C++を学ぶ、オープンソースライブラリ(私の場合はOpenFOAM)を見つける、ゼロから開発するのではなく、学習し、高度なコードを掘り下げる、その側面について学ぶ、変更する、実験、すべて特定の目的で駆動:あなたの場合、例えば空力シミュレーション。
tmaric

@ tomislav-maric、ありがとうございます。私は厳密な「パイソン人」ではありません。実際、この分野の新参者であるため、目の前にはたくさんの選択肢があります。私もOpenFOAMを学んでいます。だから私はあなたがプロジェクトに取り組み始めて、それを通して学ぶ(または手で汚れる)べきであるというあなたの意見に同意します。それはまさに私がすべきことです!ありがとう。
-Subodh

@smj btw、私も機械工学の酷似から来て、現在、計算科学の大学院生です(機械工学はこれに備えていませんでした)... OFで作業しているなら、C ++の本を検索してくださいスタックオーバーフローのリストを作成し、学習を開始します。C ++、OpenFOAM、および計算科学の知識の3つが必要です。OpenFOAMと計算科学では、樹状の方法で学習できます。課題を見つけて、それを達成し、必要なものに沿って学習します。何かを終えることはあなたのやる気を引き出します。C ++の場合:C ++入門書から始めて、それを学んでください。幸運を!:)
tmaric

回答:


19

Pythonを具体的に求めていることを考慮して、私はあなたの質問に答えようとします。シミュレーション問題に取り組む独自の方法を説明します。この説明では、より高速なシミュレーションのための戦略を示します。

最初に、Pythonで新しいシミュレーションのプロトタイプを作成します。もちろん、できる限りNumPySciPyを利用しようとしています。NumPyは数値シミュレーションに適した配列データ型を提供しますが、SciPyはNumPy配列で動作する幅広い数値ルーチンを提供します。

プロトタイプが多かれ少なかれ機能するようになったら、プログラムまたはスクリプトのどの部分がボトルネックになっているかを調べてみます。その典型的な候補があります:

  • Pythonのループは遅いです。非常に遅い。
  • Pythonはduck型を使用するため、関数の呼び出しが遅くなる可能性があります。

単純なプロファイリング戦略を使用して、すべての実行時間が費やされる場所を学習します。使用IPythonシェル(私は十分にお勧めすることはできません)、私は私のスクリプトを実行します

%timeit script.py

この「魔法のコマンド」は(timeitを使用して)プロファイリングを行い、スクリプトが終了した時点でリストを表示します。このリストを使用して、コードが遅すぎる場所を見つけます。

高速化が必要な部分を特定したら、コンパイル済み言語の使用を検討できます。2つの解決策を示します。

まず、Cython言語があります。CythonはPythonに非常によく似たプログラミング言語です(実際、Pythonコードは多くの場合有効なPythonコードでもあります)。ただし、CythonコンパイラーはCythonファイルをCコードに変換します。Cコードは、Pythonから使用可能なモジュールにコンパイルできます。CythonはNumPy配列を理解します。Cythonを使用すると、2つの方法が役立ちます。最初に、データ型を導入できます。これにより、関数呼び出しが高速化されます。また、配列を反復処理すると、ループの実行が高速になります(実際、ダミー変数と配列の両方を入力すると、単純なCループになります!)。第二に、私の実験では、型付けされていないスクリプトでさえ、解釈されるのではなくコンパイルされるという事実により、少し速く実行されます。

役に立つ他のコンパイル済み言語はFortranです。PythonでFortranを使用するにはさまざまな方法があります(f2pyfortwrapCython)。個人的には、f2pyが最も簡単な方法のように思えますが、それが何をするのかを簡単に説明します。f2pyは、FortranコードをPythonモジュールにコンパイルできます。Pythonスペースからの入力および出力変数としてNumPy配列を使用できるようになります。Fortran空間では、これらは通常のFortran配列になります。これらは、Fortranの最高速度で操作できます。

個人的には、関数呼び出しの数がボトルネックであるCythonを使用する傾向があります。ループが重いものについては、f2pyを好みます(Fortranの強力なバックグラウンドがあるためでしょう)。

Fortranに関する追加の注意事項:最新のFortranは、NumPyと非常によく似た読み取りと書き込みを行います-構文は非常に似ています。これにより、NumPyコードをFortranコードに簡単に変換できます。

Cythonとf2pyの両方が何らかの方法でパラレリズムをサポートすることに注意してください。Cythonの場合、ここでヘルプが見つかります、Fortranの場合、OpenMPやMPI などの標準的な手法があります。さらに、MPI用の P ythonラッパーもあります。個人的には、FortranのOpenMPと同様にPythonレベルでmpi4pyを使用しています。

H.-P.著「計算科学のためのPythonスクリプト」という本を少しお勧めします。Langtangenは、Python全般およびPythonを少し速くするための戦略に関する優れたリソースです。残念ながら、AFAIR、Cythonについては何も言及していません。2番目のリソースとして、これらのスライドをご覧ください。私はこの記事で言及したすべてのためにこれらの所与の例(またコードとソース参照ここに)。インターネットには他にも多くの優れたスライドがあります。

より具体的な質問がある場合は、喜んでお手伝いします!


1
Pythonプロファイラーの概要については、コードの最適化に関するscipy-lecturesも参照してください
-denis

7

CFD + Pythonには解決策があります:http : //pythonflu.wikidot.com/これらはOpenFOAMの上のPythonバインディングです(質問へのコメントで既に言及されています)。これらのバインディングにより、「ソルバーレベル」でのプログラミングが可能になります(元のOpenFOAMソルバーがPythonで複製され、元のものより遅くならない例があります。 OpenFOAMのC ++コードで)。

これらのバインディングの利点は、OpenFOAMのすべての並列化がソルバーレベルの下で行われることです。したがって、OpenFOAMコアが処理する他の要素と同様に、それを気にする必要はありません。線形ソルバー、オペレーターの離散化)

したがって、新しいソルバーを作成し、OFコアに新しい機能(境界条件、線形ソルバーなど)を追加したくない場合は、PythonFluで十分である可能性があり、C ++ Python)

PS:元々これを元の質問の議論へのコメントとして追加したかったが、私の評判は私にこれを許可していない


こんにちはベルンハルト!scicompへようこそ!:)
tmaric
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.