FortranはALPSのFortranインターフェースモジュールです。Fortranを使用し、いくつかの必要なサブルーチンを実装することで、容易にALPS上でFortranコードを実行することができます。本章ではALPS上で動作するFortranコードを書くための手順を説明します。Fortranに移植する手順やビルド設定ファイル(CMakeList.txt)の書き方についても本章で説明します。tutorials/alpsize-11-fortran-ising]]に含まれています。Fortran及びFortranで記述されたユーザーアプリケーションの関係を以下に示します。FortranはALPS本体からの呼び出しを受け、必要に応じてユーザーアプリケーションのサブルーチンをコールします。これにより、ALPSはC++で実装されたアプリケーションと同様にFortranで実装されたアプリケーションを制御できます。FortranはALPS本体の機能を呼び出すサブルーチンを提供しており、ユーザーアプリケーションは通常のFortranサブルーチンを呼び出すのと同様にALPSの機能を利用することができます。ユーザーアプリケーションの呼び出しの流れは以下のようになります。下図中の各サブルーチンについては[2.3.3]をご参照ください。Fortranを利用したアプリケーションを実装するには、最低限、下記2つのソースコードを準備する必要があります。ここではmain関数(アプリケーションのエントリポイント)、ワーカー名等のアプリケーション設定を記述します。main関数は決まった内容を記述するだけであり、通常は変更の必要はありません。アプリケーションの設定ついては以下の設定用コードを記述します。以下に、C++ソースコードの例を示します。上記例の内、変更が必要なのは赤字の部分になります。Fortranソースコードの内容は計算ロジックが主になります。Fortranを使用するためにいくつかのサブルーチンを必ず実装する必要があります。Fortranが提供するサブルーチンを経由してALPS本体の機能を呼び出します。ユーザーアプリケーションがALPSからの制御を受けるためには、Fortranソースコード内にいくつかのサブルーチンが必要になります。後述する各サブルーチンの説明をご一読の上、適切な実装を行ってください。これらを省略するとリンクエラーとなり、ビルドできません。これらのサブルーチンを実装する際は、以下の点に留意して実装してください。caller」が渡されます。callerはALPS本体の機能を利用するために内部で利用される変数です。したがって、callerの値を書き換えないでください。callerの値が変更された場合の動作は未保証になります。*各サブルーチンでは「alps/fortran/alps_fortran.h」をインクルードしてください。このファイルはFortranコードからALPS本体の機能を呼び出す際に必須になります。したがって、必須サブルーチンにつきましては、サブルーチンのシグネチャ直下に以下の3行が必要になります。本サブルーチンは計算が行われる前に一度だけコールされます。ここでは、配列の確保等、アプリケーションの初期化処理を行います。本サブルーチンは入力パラメータ1セットにつき、1回のみコールされます。本サブルーチンはalps_initがコールされた後に1度だけコールされます。ここでは、alps::ObservableSetの初期化を行います。本サブルーチンは入力パラメータ1セットにつき、1回のみ呼び出されます。alps::ObservableSetの詳細につきましては、ALPSのHPをご参照ください。計算ロジックを実装します。本サブルーチンは後述するalps_progressが1.0以上を返すまで、ALPSから繰り返し呼び出されます。したがって、本サブルーチン内ではループを記述する必要はありません。スレッド並列実行時には、本サブルーチンはマルチスレッド下で動作します。そのため、スレッド並列で利用する際にはスレッドセーフな実装を行う必要があります。本サブルーチンはalps_runが実行された後にALPSからコールされ、アプリケーションの進捗状態をALPSに返します。prgrsが1.0未満の間、ALPSは繰り返しalps_runをコールします。prgrsに1.0以上の値を代入すると、ALPSは計算が完了したとみなし、アプリケーションを終了します。スレッド並列実行時には、本サブルーチンはマルチスレッド下で動作します。そのため、スレッド並列で利用する際にはスレッドセーフな実装を行う必要があります。本サブルーチンはalps_runが実行された後にALPSからコールされ、サーマライズの完了/未完了を返します。thrmlzの値が0の場合、アプリケーションがサーマライズ中であるとみなし、計算結果を保存しません。thrmlzが1になるとサーマライズが完了したとみなし、計算結果の保存が開始されます。スレッド並列実行時には、本サブルーチンはマルチスレッド下で動作します。そのため、スレッド並列で利用する際にはスレッドセーフな実装を行う必要があります。本サブルーチンは計算が完了した後(alps_progressが1.0以上を返した後)に1度だけコールされます。ここでは、alps_initで確保したメモリの解放等の終了処理を行います。alps_runが実行された後にALPSからコールされます。ここではALPS本体の機能を利用してリスタートファイルの保存を行います。スレッド並列実行時には、本サブルーチンはマルチスレッド下で動作するため、スレッド並列で利用する際にはスレッドセーフな実装を行う必要があります。本サブルーチンはアプリケーションがリスタートされたときに1度だけコールされます。ここでは、ALPS本体の機能を利用して、保存されたリスタートファイルをロードします。Fortranが提供するサブルーチンをコールします。caller」が必要になります。Fortranから渡される内部変数であり、必須サブルーチン(2.2.3.1)に引数で渡された変数をそのまま提供サブルーチンに渡す必要があります。名前を指定して、ALPSからパラメータを受け取ります。パラメータの名前、型、要素数はそれぞれname、type、countで指定します。本サブルーチンは主にalps_init内で配列や変数の初期化に利用されます。typeが取りうる値はalps_fortran.hに定義されています。nameで指定したパラメータがパラメータファイルに定義されているかどうかを返します。パラメータが定義されていればresに1が代入されます。定義されていなければ0が代入されます。本サブルーチンは主にalps_init内で配列や変数の初期化に利用されます。本サブルーチンは、alps_init_observable内でalps::ObservableSetにnameで指定されたObservableを登録するために使用します。Observableの種類はcount及びtypeによって以下のように決定されます。計算結果)を保存します。本サブルーチンはalps_run内で計算結果を保存するために使用します。init_observableで指定したものと一致している必要があります。本サブルーチンは、alps_save内でリスタートファイルを保存するために使用します。alps_dumpを使用して保存した中断データはリスタート時に使用されます。本サブルーチンは、alps_load内でリスタートファイルをロードするために使用します。リスタートファイル内にはalps_dumpで保存した順にデータが保存されます。したがって、alps_restoreでロードする際は保存時と同じ順番でデータを取り出してください。ユーザーアプリケーションはALPS同様、CMakeを使ってビルドします。以下はユーザーアプリケーションをCMakeでビルドするための設定ファイル(CMakeLists.txt)のサンプルです。上記例のうち、変更が必要なのは赤字の部分になります。本節では、以下に示すisingプログラムを例に、既存のFortranアプリケーションをALPS上で動作させるための手順について説明します。tutorials/alpsize-11-fortran-ising]]のファイルを使用します。tutorials/alpsize-11-fortran-ising]]フォルダ内の以下のファイルを作業ディレクトリにコピーしてください。template.f90にはFortranでALPSアプリケーションを実装する際に必要となる全てのサブルーチンが定義されています。そのため、新規アプリケーションを開発する際はtemplate.f90を元に開発進めることができます。移植元コードの大まかな構造は以下の通りです。Fortranコードの移植では、ising_original.fの各ブロックで行われている処理を、サブルーチンに割り当てていきます。ising_impl.f90]]を例に説明します。ising_original.f内で宣言されている各変数はALPS移植時にはmodule化します。ALPSに移植するためには処理単位ごとにサブルーチン化する必要があるため、各サブルーチンから変数にアクセスできるようにするためです。配列IP、IM、IS、Pはalps_init内で初期化するため、ここでは移植後はサイズ指定しません。移植元コードの配列Aは結果保存用の配列ですが、移植後はALPSの仕組みを利用します。したがって移植後のコードに配列Aは必要ありません。移植後の各変数の値は、パラメータファイルから取得します。移植後の変数Kは繰り返し回数をカウントするための変数です。移植後はdoループを使わずにKの値で繰り返し制御やサーマライズチェックを行います。'''※本節ではMPI並列での実行を想定しているので、スレッドセーフについては考慮していません。移植元コードの初期化処理は配列の各要素を初期化していますが、移植後コードでは初期化処理をalps_initサブルーチンで実行します。最初にalps_get_parameterを使用して変数・配列の初期化を行い、その後配列要素の初期化を行います。移植後は結果保存用の配列を用意せず、alps_init_observableサブルーチン内で結果保存用のObservableを用意します。alps_init及びalps_init_observableはALPSから自動的にコールされるので移植後コード内でコールする必要はありません。移植後は21~24行目でalps_get_parameterをコールしており、ALPSを通してパラメータファイルの内容を取得しています。34~51行目の処理は移植元と同じです。移植後は計算結果の保存用バッファとして"Energy"及び"Magnetization"という名前でObservableを用意しています。移植元ではEnergy及びMagnetizationそれぞれについて総和と二乗和を計算していますが、これらの計算はObservableが自動的に行います。移植元コードではdoループ内(移植前25行目)で繰り返し計算を行っていますが、移植後はdoループを使わずにalps_run及びalps_progressサブルーチンを使用します。計算処理自体(65~82行目)は移植元と同じですが、移植後はalps_runが自動的に繰り返しコールされるので、移植前の25行目にあたるループは記述しません。その変わり、86行目で繰り返し回数をカウントします。計算結果の保存はALPSの機能を使用します(84、85行目)。移植元では積算、二乗計算等を行っています(移植元43~46行目)が、これらはalps_accumulate_observableで自動的に行われます。移植後は繰り返し計算の制御をalps_progressで行います。prgrsが1以上になるとalps_runがコールされなくなるので、カウンタ(K)の値を監視し、規定回数分実行されたらprgrsが1以上になるよう実装します。移植前のサーマライズチェックはメインループ内(36行目)で行われていますが、移植後はalps_is_thermalizedサブルーチンで行います。移植後はalps_progress同様、カウンタ(K)の値からサーマライズのチェックを行います。thrmlzが1になるとサーマライズが完了したとみなされます。ALPSを使用すると結果の後処理や出力は自動的に行われます。したがって、移植後は計算結果の後処理・出力用のコードは必要ありません。移植前のコードではallocateを行っていないため終了処理がありません。移植後はalps_init内でallocateした領域を終了時に開放する必要があります。alps_load)を実装するだけで、アプリケーションにリスタート機能を追加できます。移植元にはリスタート機能がありませんが、以下にALPSによるリスタートファイルの入出力機能の実装例を説明します。alps_saveではリスタートに必要なる変数のみをalps_dumpで書き出します。ここでは、カウンタ(K)及び計算途中のデータ(IX、IS)を書き出しています。alps_loadではalps_saveで書き出した(alps_dump)順番で読み込む(alps_restore)する必要があります。ALPSアプリケーションをリスタートした場合、alps_loadが呼ばれる前にalps_initが呼ばれます。K、IX、ISのメモリ確保や他の変数の初期化はalps_init内で行われるので、alps_load内で初期化等を行う必要はありません。ALPSアプリケーションをマルチスレッドで動作させる場合、Fortranコードをスレッドセーフな実装にする必要があります。本節で説明したtutorial.f90の場合、2.4.2で準備した変数をスレッドローカルにすることでマルチスレッドに対応することができます。ising.Cはアプリケーションのエントリポイントになるため、必須のファイルです。main関数については内容を変更する必要はありません。アプリケーション設定に関しては[[#サブルーチン呼び出しの流れ]]を参照の上、必要に応じて変更してください。以下にCMakeLits.txtの例を示します。ALPSDisclaimers。