124. FDPS (2015/3/20)
3月17日、私達「理化学研究所計算科学研究機構粒子系シミュレータ研究チー
ム」は、粒子系シミュレーションのための汎用プラットフォーム "FDPS"
(Framework for Developing Particle Simulator) のイニシャルリリース、
Version 1.0 を
公開しました。
ソフトウェアは githubで公開しています。
インストールからサンプルプログラムコンパイル、実行までのチュートリアルも用意しました。
ここでは、FDPS とはどういうもので、何ができるか、また、どういう考え方
で開発されているかについての、私の個人的な考えを述べます(チームないし理研
公式のものというわけではありません)。
FDPS は、粒子系シミュレーションのための「汎用」プラットフォームです。
つまり、粒子系であればどんなものにでも適用できることを目標にしています。
普通、そのような「汎用」プログラムは問題や使う計算機特定で人がチューニ
ングしたプログラムに比べて遅くて話にならないのですが、FDPSでは粒子系シ
ミュレーションの並列化の十分良いアルゴリズムを採用することで、
多様な問題に対して世界最高レベルの実行効率を実現します。
ちょっとホラを吹き過ぎではと書いているほうも思わなくものないので、
読むほうがは一層そうかもと思いますが、全くホラというわけでもないので
もうちょっと我慢して読んでみて下さい。
FDPS で扱う粒子系は以下のようなものです。
-
系が粒子の集まりとして表現される
-
粒子は位置、速度をもち、粒子間相互作用によって力をうけて運動する
-
2つの2粒子間の相互作用は、それらの相対位置と、それぞれが持つ
内部情報から計算できる。相互作用(のうち計算量が多い部分)は2体力とし
て表現できる。
-
粒子間相互作用は、2つの粒子の距離が大きくなると弱くなる。
FDPSの中では有限距離でカットオフがあったり指数関数的に落ちる場合
(近距離力とよぶ)と、重力やクーロン力のように距離の弱いべきで
落ちる場合がある
このような系を、陽解法で時間積分していくプログラムの作成を容易にすることが FDPS の目標です。
この想定で、重力多体系、SPH 法や他のラグランジュ的な粒子法で表現された
流体や構造体、分子動力学といったものを扱うことができます。タンパク分子
の分子動力学のような、分子結合による力(結合力)が働く場合にも、結合に依
存しないクーロン力やファン・デル・ワールス力はFDPSで扱い、結合力は
FDPSを使って応用プログラムを書く開発者が書いたコードで計算することがで
きます。
FDPS の実装上の考え方は、以下のようなものです。
-
アプリケーション開発者は、
-
粒子の定義(粒子クラスの定義)
-
粒子間相互作用の定義(粒子間相互作用を計算する関数)
を記述する。
-
FDPS はこれらを受け取ることができるテンプレートクラスライブラリの形で
以下を行う関数群を提供する
-
粒子の空間分布と計算ノードの数に応じた領域分割を行い、
ノード間で粒子を交換して粒子を再配置する
-
受け取った相互作用計算関数を使って、粒子間相互作用を計算する
このために、遠距離相互作用の場合にはツリー法を使う。近距離力の場
合、現在の実装ではツリー法によって近接粒子リストを構築し、
それを使って相互作用を計算する。
-
アプリケーション開発者は、FDPS が計算した相互作用を使ってシステムを
アップデート(時間積分とか)する。以下、
空間分割(これはスキップ可能)、粒子移動、相互作用計算、アップデート
を繰り返す。
最近の計算機では、
-
分散メモリの複数ノード計算機での、データ分割、移動
-
OpenMP 等によるノード内並列化
-
SIMD ユニット有効利用、キャッシュ有効利用
といったことを考える必要がありますが、FDPS は粒子データと
相互作用計算関数を渡されれば 1, 2 を「おまかせ」でやります。
空間分割はゴードンベル賞を獲得した宇宙論N体計算コード GreeM
で採用した直交多重分割を使っています。これは伝統的に使われてきた
正規直交分割が、ノード数が2のべきでないと使えないという問題を
回避するため、x, y, z の3軸を任意の数で分割できるようにしたものです。
相互作用計算のためには、各ノードが、他のノードで必要になる
自分の情報(いわゆる local essential tree) を作って、他に送り、
受け取った情報から全体ツリーを再構成して相互作用計算をします。
この時に複数スレッドを使うので、アプリケーション開発者
が書く相互作用計算関数はマルチスレッド化の必要はありません。
FDPS で想定する相互作用計算関数は、1ペアの粒子間の計算ではなく、複数粒
子から複数粒子への力をまとめて計算する形で定義するようにしています。
この形にすることで、キャッシュの再利用や SIMD化を容易にしています。
GPU 等のアクセラレータを使う場合には、これだけではアクセラレータの計算
カーネルの起動オーバーヘッドや並列性を隠蔽するには十分ではないので、
この関数を複数並列に呼び出すようにインターフェースを拡張する必要があり
ます。これは今回公開した Version 1.0 ではまだサポートできていませんが、
今年中には対応する計画です。
実際のノード間通信による粒子交換や相互作用計算のためのデータ転送は
MPI を使って実装されています。この、MPI の呼び出しは完全に
FDPSの中だけで行われるので、アプリケーション開発者の書くプログラム
は FDPS の関数を呼び出すと、勝手に粒子が入れ替わったりするけれど
その部分を書く必要はない、ということになります。
このため、FDPS を使ったコンパイル時のオプションと使うコンパイラの
指定を変えるだけで、1コアで動作するプログラム、OpenMP で並列化sれた
プログラム、MPIで並列化されたプログラムが生成されます。OpenMP や
MPI による並列化は FDPS 側で十分に最適化されていますので、
アプリケーション開発者はその部分に注力する必要はありません。
相互作用計算のルーチンは現在のところまだSIMD命令やキャッシュに対してちゃ
んと最適化したものをアプリケーション開発者が作る必要があります。但し、
これは、相互作用を及ぼす粒子、受ける粒子共に複数ある、2重ループの
最適化なので、それに特化したコンパイラ、例えば
KFCR社の Goose コンパイラ
を利用することも可能です。
概念はこのようなものとして、実際に使いものになるためには
I/O、色々な境界条件のサポート、その他色々な機能が必要になります。
それらは、我々が考えつくものはいれていますが、アプリケーションによって
はもっと機能が必要かもしれません。これらについてはご意見をいただ
けるとありがたいです。
現在、サンプルコードとしてはまだ重力多体と単純な周期境界での SPH だけ
しかはいっていませんが、レナードジョーンズポテンシャルでの分子動力学
コードも記述して動作することは確認しています。また、重力とSPHというふ
うにタイプの違う複数の相互作用がある系も記述できます。
周期境界もサポートします。長距離力の場合には、長距離は FFTで、短距離は
ツリーで、という TreePM法を使います。短距離力は単純にミラーイメージか
らの力を計算します。
重力多体コードの場合、I/O やログメッセージの生成を除いた、実際の時間積
分プログラムは200行程度です。SPHは相互作用自体が複雑なのでもっと長いで
すが、MPIで並列化された、アダプティブな空間分割を行う重力多体プログラム
は1万行近く、SPH ではさらに長くなるのに比べるとアプリケーションプログラ
ムの記述は単純な1コアでの、しかもツリーとかネイバーリストとか使わないプ
ログラムとほぼ同じ量ですむことになります。
私達が FDPS の開発を始めた目的は、基本的に、1コアで動くプログラムを書け
る人が、自分で書いたプログラムを大規模スパコンで効率的に実行できる
ようにする、ということです。なかなか夢のような話にみえますが、
粒子系シミュレーションに限っていえば、
FDPSの枠組みにのってプログラムを書けば、それが実現可能になった、と
考えています。