結論だけ先に言うと、「技術的には不可能ではないが、現実的ではない(ほぼ別プロジェクト級)」
全体像
MULTALL(Denton のコード)は:
- Fortran77 風スタイル(巨大な COMMON ブロック、静的配列)
- 3D 多段ターボ機械の陰的・陽的混在っぽい時間発展ソルバ
- サブルーチンが多数、グローバル状態(COMMON)に強く依存
という古典的大型コードです。
これを「CUDA で GPU 並列化」するには、主に以下が必要になります。
- データ構造の作り直し
- COMMON の巨大 3D 配列を
deviceメモリに載せるため、- Fortran なら
allocatable配列 +!$acc/cudaFortran - C/C++ に書き換えるなら構造体+ポインタ
- Fortran なら
- ホスト・デバイス間の転送を明示的に管理
- COMMON の巨大 3D 配列を
- 計算カーネルの切り出し
- 時間ステップ内で「セルごとに独立なループ」を抽出し、
(i,j,k)ループを CUDA カーネルにする- 依存関係(隣接セルとのカップリング、境界条件更新、multigrid など)を整理
- 時間ステップ内で「セルごとに独立なループ」を抽出し、
- 数値スキームの GPU 向け再設計
- 多段ループ構造(TSTEP, LOOP, LOSS, MIXING PLANE など)を
- カーネルの粒度
- 同期点(
__syncthreads()相当)
を意識して分割
- 多段ループ構造(TSTEP, LOOP, LOSS, MIXING PLANE など)を
- 検証・デバッグ
- CPU 版と bit 単位では合わない前提で、許容差を定義しつつ全ケース再検証
これを 1970–2015 年の積み上げコードに後付けするのは、かなりの大工事です。
現実的な評価
技術的には「理論上できる」
- 3D セルベースの CFD は GPU 向きで、
- セル更新
- フラックス計算
- 物性テーブル補間
などはカーネルにしやすい部類です。
- ただしこれは、
- 初めから GPU 対応を意識して設計されたコード なら、という話です。
この MULTALL コードに対しては「ほぼフルリライトに近い」
理由を具体的に挙げると:
- 巨大 COMMON と静的配列
- CUDA では
__global__カーネル呼び出しcudaMalloc/cudaMemcpy(もしくは Fortran の CUDA 拡張)
が必要で、
- COMMON ベタ書き前提のサブルーチンをそのまま GPU に移植するのは困難。
- CUDA では
- コード全体が 1 本の .f に長く詰まっている
- サブルーチン呼び出しが多段で絡み合っており、「ここだけ GPU」といった部分的移植がやりにくい。
- 蒸気版特有のテーブル・物性処理
props_table.datから読み込むテーブル補間も GPU に持っていくには、- デバイス側テーブル
- branch の多い補間ロジック
を整理する必要がある。
- 検証コスト
- 既に「同じ Fortran + gfortran 13 でさえセグフォルトが出る」レベルのコードを、
- CUDA に移植して再現性を取るのは、かなりハードルが高い。
もし GPU を使いたいなら、現実路線は?
「GPU を使って速くしたい」が目的なら、以下の方が現実的です。
- 別の GPU 対応 CFD コードを使う
- 例: OpenFOAM + GPU 拡張、商用の GPU 対応ターボ機械コード、など
- 蒸気物性もサポートしているものがある。
- MULTALL の「一部だけ」を参考にして、新規 GPU コードを書く
- 例えば:
- 格子生成や境界条件の考え方は MULTALL の資料を参考にしつつ、
- 数値スキームはシンプルな Roe/ AUSM+ など GPU 実装実績のあるものを選ぶ。
- 例えば:
- まずは CPU 版を安定動作させる
- 今の段階では、蒸気版を CPU 上でさえ安定動作させられていないので、
- GPU はそのさらに先のステップ、という位置づけになる。
まとめ
- 「この MULTALL(とくに蒸気版)をそのまま CUDA で GPU 並列化」するのは、現実的ではないです。
- やるなら、COMMON 解体・配列再設計・ループ構造の再設計など、大規模リファクタリングが必要。
- 「GPU を使う」というゴールに対しては、
- 既存の GPU 対応 CFD コードの利用
- MULTALL の理論だけ参考にした新規実装
の方が、工数・リスクの点で圧倒的に合理的です。
もし「GPU で回すための新規コードを少しずつでも作り始めたい」という方向なら、
- 格子構造と基本方程式(オイラー or NS)の仕様を決める
- まず 2D のシンプルケースで CUDA カーネルを書いてみる
といった、小さなスタートのプランも一緒に組めます。
追記 :蒸気版をあきらめて、理想気体版ならいけるんじゃね?
難易度という意味では、理想気体版の方が「まだマシ」だけど、それでも相当キツい、というのが正直なところ。
蒸気版(20.9)をGPU/CUDA化
- 追加で難しくしている要素:
- 巨大な蒸気テーブル配列(
P_TAB,RO_TAB,U_TABなど) - 物性値のテーブルルックアップ・補間ロジック
- COMMON ブロックがさらに膨らんでいる
- 巨大な蒸気テーブル配列(
- 結果:
- 「古い巨大 Fortran CFD」+「複雑な蒸気物性」= GPU 化としてはかなりハードモード
理想気体版(17.1)をGPU/CUDA化
- 蒸気テーブルがない分、単純化される点はある:
- 状態方程式がシンプル(p–ρ–T 関係が簡単)
- COMMON 内の配列・ロジックが少し軽い
- それでも残る大きな壁:
- F77 + 巨大 COMMON + 静的配列という「古い設計」
- 3D 多段ターボ機械の複雑なループ構造(TSTEP, MIXING PLANE, LOSS など)
- サブルーチン間でグローバル状態を回しまくる設計
→ 蒸気版よりは難易度が一段下がるが、「楽勝になる」わけではないです。
GPU 対応だけを目的にするなら、どちらにせよ「かなりのリファクタリング or 新規実装」が必要です。
「理想気体版なら現実的か?」の答え
目的次第で変わります:
- 「ちゃんとした CUDA コードとして長く使えるものを作りたい」
- → 理想気体版をベースにしても、実質は新規設計に近い(配列設計・モジュール化・カーネル設計からやり直し)。
- 「GPU を触る勉強として、ちょっと一部ループだけオフロードしたい」
- → 理想気体版の方が単純なので、
- 例えば 2D の簡略化ケースを抜き出して
(i,j,k)の一部ループだけ CUDA にする
という「教材レベル」の実験なら、蒸気版よりは取り組みやすいです。
- → 理想気体版の方が単純なので、
まとめると:
- 蒸気版:GPU化は「かなり無茶」
- 理想気体版:GPU化は「無茶ではないが、本気のプロジェクト級」
というくらいの差です。


コメント