Fortran との対応表
Fortran で書いていた処理を、C++ と MISO でどう書くかを引くための表です。 左の列で Fortran の書き方を探し、右の列の書き方と、説明している章へ進んでください。 表の対応は「同じ目的に使う書き方」の対応で、意味が完全に同じとは限りません。違いがある行には注意を書いています。 ソースのパスは、MISO を clone したフォルダからの相対パスです。
目次
1. プログラムの構成
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
|
|
|
不要 |
C++ では、すべての変数を宣言してから使います。暗黙の型はありません |
|
|
|
||
行の継続 |
不要 |
文は |
|
大文字と小文字を区別しない |
区別する |
|
|
|
|
|
|
|
|
|
|
ソースファイル |
ヘッダ |
ヘッダの中のテンプレートでない関数には |
|
初期化の |
オブジェクトを作るとコンストラクタが動く( |
後片付けはデストラクタが自動で行います |
2. 型・宣言・定数
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
関数の中の |
|
|
|
||
|
|
||
|
|
MISO のデモは |
|
|
|
C++ の |
|
|
|
||
|
|
長さは自動で決まり、 |
|
|
|
MISO の \(\pi\) は |
|
|
|
||
|
|
どちらも 0 の方向へ切り捨てます |
|
型を書かずに右辺から決める書き方はない |
|
右辺の型がそのまま変数の型になります |
3. 演算子と組み込み関数
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
C++ にべき乗の演算子はありません。 |
|
|
|
どちらも結果は 3 です |
|
|
|
負の数でも符号の規則は同じです(割られる数の符号) |
|
|
|
|
|
|
|
||
|
|
||
|
|
|
|
|
|
||
|
|
||
|
|
出力ファイル名に使います |
4. 制御文
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
条件は |
|
|
|
0 から始まり、上限 |
|
|
|
||
|
|
MISO の時間ループは |
|
|
|
C++ の |
|
|
|
各 |
|
|
|
|
5. 配列
5.1 宣言と確保
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
宣言と確保が同時です。 |
|
|
不要 |
|
|
|
|
||
|
|
MISO は変数ごとに別の配列を持ちます( |
|
|
|
次元の番号も 0 から数えます |
5.2 添字の始まりとゴーストセル
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
||
|
添字は常に |
MISO の配列は下限を変えられません。 |
|
|
|
5.3 メモリ上の並び
Fortran は最初の添字が連続(列優先、column-major)、MISO の Array3D は最後の添字が連続(行優先、row-major)です。
同じ a(i, j, k) と書いても、メモリ上で隣にある要素が違います。
Fortran の |
MISO の |
|
|---|---|---|
メモリ上で隣の要素 |
|
|
速く回すループ(最も内側) |
|
|
要素の位置( |
|
|
次の短いプログラムは、MISO の Array3D で要素がメモリの先頭から何番目にあるかを表示します(説明用の例)。
// order.cpp: check the memory layout of Array3D
#include <iostream>
#include <miso/array3d.hpp>
int main() {
miso::Array3D<double> a(2, 3, 4); // a(i, j, k): i < 2, j < 3, k < 4
const double *p = a.data(); // address of the first element
// difference between an element's address and the first address = offset from the start
std::cout << "a(0,0,1): " << &a(0, 0, 1) - p << "\n";
std::cout << "a(0,1,0): " << &a(0, 1, 0) - p << "\n";
std::cout << "a(1,0,0): " << &a(1, 0, 0) - p << "\n";
std::cout << "a(1,2,3): " << &a(1, 2, 3) - p << "\n";
}
a(0,0,1): 1
a(0,1,0): 4
a(1,0,0): 12
a(1,2,3): 23
k を 1 増やすと隣(1 番目)、j を 1 増やすと 4 個先、i を 1 増やすと \(3 \times 4 = 12\) 個先です。
Fortran で同じ大きさの配列 a(2, 3, 4) を作ると、a(2, 1, 1) が先頭から 2 番目(1 始まり)になり、i の方向が連続します。
MISO の出力ファイル(mhd/mhd.*.bin)もこの並びで書かれるので、Fortran や NumPy で読むときは添字の順に注意します。
5.4 配列の式と部分配列
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
ループ、または |
C++ の配列型に、配列全体の演算の書き方はありません |
|
|
|
CPU と GPU の間のコピーにも使います |
|
|
|
最小値なら |
|
|
ループの中の |
||
部分配列を引数に渡す |
View( |
MISO の View は配列全体を指す軽い窓です。部分配列を切り出す機能はありません |
6. 手続き(subroutine・function)
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
戻り値のない関数です |
|
|
|
戻り値の型を名前の前に書き、 |
|
引数は参照で渡す(既定) |
引数は値で渡す(既定)。参照で渡すには |
|
|
|
小さな値は値渡し( |
|
|
|
|
||
|
既定の引数 |
|
|
|
同じ名前で引数の型が違う関数を定義する(オーバーロード)、テンプレート |
|
|
|
関数の宣言(ヘッダに書く) |
||
|
関数テンプレート |
1 つの定義から型ごとの関数が作られます |
|
|
|
GPU から呼ぶ関数には |
|
|
不要 |
C++ の関数は、そのまま自分を呼べます( |
|
|
ラムダ式 |
周りの変数をコピーして持ち込みます(キャプチャ) |
|
手続きを引数に渡す( |
関数オブジェクトやラムダを引数に渡す( |
7. module と use
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
ヘッダファイルと |
名前の衝突を避ける役割は名前空間、中身を共有する役割は |
|
|
|
|
|
|
|
1 つの名前だけを使えるようにします( |
|
サブモジュールや入れ子の分類 |
入れ子の名前空間 |
||
|
慣習として |
名前空間には |
|
module 変数(プログラム全体で 1 つ) |
名前空間の |
MPI のランクは |
|
|
|
8. 派生型
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
||
|
|
成分の参照は |
|
構造体構成子 |
コンストラクタ |
初期化子リスト |
|
型束縛手続き |
メンバ関数 |
|
|
|
デストラクタ |
寿命の終わりに自動で呼ばれます |
|
|
継承 |
||
|
仮想関数 |
MISO は仮想関数を使わず、 |
|
パラメータ化派生型 |
クラステンプレート |
9. pointer と allocatable
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
仮引数の別名(引数で受けた配列を書き換える) |
参照 |
参照は作ったときに指す先が決まり、付け替えられません |
|
|
|
|
|
|
|
||
配列ポインタで配列を指して渡す |
View( |
View は確保・解放をしない軽い窓で、ラムダにコピーして GPU にも渡せます |
|
|
|
コピーは禁止または明示( |
|
|
|
10. 入出力とエラー処理
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
||
|
YAML の設定ファイルと |
書かなかった値は |
|
|
|
MISO の出力は |
|
|
|
||
|
|
MISO では、実行時のエラーを例外で知らせます |
|
ファイル名を文字列で連結する |
|
|
11. MPI
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
||
|
|
||
最後の引数 |
関数の戻り値 |
C++ では |
|
|
|
||
|
|
|
|
|
|
スカラーは |
|
|
|
||
|
|
||
ランク番号、 |
同じ |
ランクと座標は Fortran でも 0 から始まります |
|
|
同じ関数( |
周期境界の方向では、端の隣が反対側の端になります |
12. 並列化の指示文とビルド
Fortran |
C++・MISO |
注意 |
説明 |
|---|---|---|---|
|
|
MISO は OpenMP を使いません。CPU 版の |
|
|
|
||
|
|
同じラムダが CPU と GPU の両方で動きます |
|
|
|
||
|
同じ( |
||
Makefile |
|
||
|
|
ここまでの書き方を組み合わせた計算は、第 10 章 の熱伝導で自分で書き、第 11 章 で MISO 本体の時間発展として読みます。