前回は、非常に簡単なプログラムを例として、データ転送の最小化について考えました。

​今回はもう少し実践的な例として、拡散方程式を扱います。

拡散現象シミュレーションのOpenACC化

図1:インクの拡散現象のシミュレーション
​図1:インクの拡散現象のシミュレーション

今回は、前回行ったデータ転送の最小化が如何に重要なのかを知ってもらうために、拡散現象のシミュレーションプログラムをOpenACC化してみましょう。

図1のように、コップに落としたインクが拡散し、最後は均一な色になる現象をシミュレーションします。

図2:計算格子とタイムステップ
図2:計算格子とタイムステップ

この現象をプログラムの中で扱うために、図2のようにコップの中の空間を格子状に区切り、配列として扱います。

このコップの中の状態を表す配列を、時刻 n の時点の状態から時刻 n+1 の状態を計算、n+1 の状態から n+2 を計算… といった要領で更新していきます。

この計算では、一つ前の時刻のコップの状態さえ覚えておけば、次の時刻の状態を計算できるので、コップの状態を表す配列を二つ用意し、交互に更新することでシミュレーションを進めます。

この例題のように、空間を格子状に切り、タイムステップを刻みながら更新を行う手法は、多くのシミュレーションプログラムで使われています。

図3:2次元拡散方程式の離散化例
図3:2次元拡散方程式の離散化例

式の形で表すと図3のようになります。
この式に従って各格子点を更新していくと、図3の下のようにインクが拡散していく様子がわかります。

図4:拡散シミュレーションの疑似プログラム
図4:拡散シミュレーションの疑似プログラム

図1から図3では2次元の場合を図示しましたが、図4は3次元の場合の疑似プログラムです。
配列 f1, f2 はそれぞれ、一つ前の時刻と現時刻のコップの状態を表しています。

これを元にOpenACC化を考えてみましょう。

まず、どのループがOpenACCで並列化可能であるかを考えなくてはなりません。
​以前の記事で書いた通り、OpenACCではデータ独立(independent)なループか、リダクション(reduction)のループしか並列化できないのでした。

一番内側の x のループから考えてみます。x のループ長は nx ですから、nx 人の小人さん(スレッド)で処理を分担し、x = i  の時の処理を i 番目のスレッドが担当するとしましょう。

すると、i 番目のスレッドは f1[z][y][i+1] を含む7箇所を読み込み、f2[z][y][i] に書き込みます。
i+1 番目のスレッドは、f2[z][y][i+1] に書き込みますので書き込み先は独立ですが、f1[z][y][i+1] を含む7箇所を読み込みますので、読み込み先は i 番スレッドと被ってしまっています。

これは、データ独立なループと言えるのでしょうか…?

答えは、言える、です。

これはデータ独立なループです。この x ループの実行中、f1 は読み込みのみで変更されませんから、別のスレッドによって意図せず変更されてしまうといったことは起こりません。
同様に考えてみると、y と z のループもデータ独立なループと言えます。

では、t のループはどうでしょうか。

疑似的に書いていますが、13行目で f1 と f2 を交換しています。
またはもっと単純な実装を考えれば、一つ前の時刻の状態を覚えていればいいわけですから、f2 を f1 にコピーするという方法も考えられます(遅いのでしませんが)。

つまり、13行目で f1 を書き換えているわけです。
従って、スレッド間で読み込み先が被っていてかつ、ループの実行中に変更される配列 f1 が存在するため、​t のループはデータ独立でなく、OpenACCでは並列化できません。

以上を踏まえると、図5のようなOpenACCのプログラムができそうです。

図5:拡散シミュレーションの疑似OpenACCプログラム
図5:拡散シミュレーションの疑似OpenACCプログラム

さてこのコード、これで完成でよいでしょうか…?よくないですね!

このままでは、答えこそ正しいものの、f1 と f2 がCPUとGPUの間で無駄にコピーされてしまいます。2行目の data指示文を1行目に変更し、データ転送を最小化するまでが必須の手順です。
手元の環境では、この差によって60倍程性能に差が出ました。

次回は、このシミュレーションを元に、loop指示文などのもう少し詳細な使い方について解説します。

1ヵ月間有効のスパコンお試しアカウント

東京大学情報基盤センターでは、教育の一環として、制限はあるものの一ヵ月の間有効なスパコンアカウントを提供しています。

現在3つのスパコンが運用されていますが、そのうちReedbushと呼ばれるスパコンには、一世代前のものではありますがGPUが搭載されていて、OpenACCを使える環境も整っています。

自分でどんどん自習したい場合は、ご利用を考えてみてください。

トライアルアカウント申し込みページ
https://www.cc.u-tokyo.ac.jp/guide/trial/free_trial.php

< 過去の講習会の資料やプログラム公開中 >

東大センターが行った過去のOpenACCに関する講習会の資料やプログラムも公開されていますので、自習する場合にはぜひご利用ください。オンライン講習会 定期開催中!

講習会ページ
https://www.cc.u-tokyo.ac.jp/events/lectures/

講習会で用いているプログラム
https://www.dropbox.com/s/z4fmc4ibdggdi0y/openacc_samples.tar.gz?dl=0​