2017-10-09 22 views
2

Fortran 77プログラムを異なる入力パラメータセットで複数回実行したい。私はすでに使用しているさまざまな入力パラメータに対して出力ファイル名が変更されていることを確認しましたが、パラメータを変更するたびにコードに行く必要がなく、入力パラメータの異なるセットでプログラムを実行する方法がわかりません。異なる入力パラメータでFortranを複数回実行する

私の質問を説明するために、ここでは簡単なコードです。

PROGRAM CODE 
    IMPLICIT DOUBLE PRECISION (A-H, J-Z) 
    COMMON/param/radius 

    radius = 2 
    write(*,*) 'radius = ', radius 
    write(*,*) 'the area is = ', 3.14*radius*radius 

    END 

は、私は異なる半径でこのコードを実行したいとして、代わりにコードにアクセスし、手動で値を変更するので、私は異なるパラメータの選択でファイルを持って、それを複数回実行したいです。

もちろん、さまざまなパラメータの選択とループの配列を作成することによって、これに対する解決策があります。しかし、私は実際に実行するたびに変更したい複数のパラメータを持っているので、私はこれをしたくありません。

以下のコメントの1つにお答えすると、実行ごとに入力の選択肢が異なるファイルがある場合、実行するたびに異なるパラメータを選択するためにプログラムをどのようにして別の行にするのですか?

+3

よくある人は、好みのスクリプト言語で少しのスクリプトを書いて、プログラムの各実行にいくつかの入力パラメータを与えることができます。本当の答えのようなものについては、質問をしてください。 –

+1

Get_command_argument – agentp

+1

さらに別のオプションは、実行ごとに必要な入力パラメータを含むデータファイルを読み込むことです。 –

答えて

6

私は何度も使用してきた「歩行者」タイプのアプローチがあります。

再コンパイルを避けるには、パラメータファイルの名前をハードコードし、このファイルからデータを読み取る方法があります。コードを実行するたびに、それ自身のパラメータのコピーとそれ自身のディレクトリが必要です。

以下は、単一のパラメータの例ですが、必要に応じて一般化できます。これはbashのドライバスクリプトに依存しています。

のFortranプログラム:

 PROGRAM CODE 
     IMPLICIT DOUBLE PRECISION (A-H, J-Z) 
     COMMON/param/radius 

     open(11, file='parameters.txt') 
     read(11,*) radius 
     close(11) 
     write(*,*) 'radius = ', radius 
     write(*,*) 'the area is = ', 3.14*radius*radius 

     END 

bashのプログラム:

for radius in 01 02 05 10 
do 
RUNDIR=run_${radius} 
mkdir ${RUNDIR} 
echo "${radius}" > ${RUNDIR}/parameters.txt 
(cd ${RUNDIR} ; ../code) 
done 

Fortranコードコンパイル:

gfortran -std=legacy -o code code.f 

をパラメトリックランを実行するよう:

bash parametricrun.sh 
  1. Fortranコードの機能:parameters.txtという名前のファイルを開き、radiusの値の最初のエントリを読み取ります。

  2. bashスクリプトは何:パラメータの値の数については、そのディレクトリにparameters.txtという名前のファイルを作成し、新しいディレクトリを作成し、そのディレクトリでのFortranプログラムcodeを実行します。

コメント:

  1. これはbashのプログラムで第二のループを使用して、いずれか一方parameters.txtにおける行当たり行ごとまたはいくつかの、いくつかの変数に拡張することができます。

  2. 最新バージョンのFortranを使用できる場合は、それに言及してください。そこにはさらに多くのオプションがあります。

  3. 他の言語(arclightが示唆するようなPython、または他のもの)をスクリプトに使用できます。多くのコンピューティングクラスターはbashを使用してジョブを実行します。そのため、パラメトリック実行に使用される可能性があります(半径の値はジョブキューイングシステムを介して渡されます)。

  4. ファイルユニット番号に任意に11を使用しました。あなたの実際の状況では、あなたのプログラムに利用可能なユニット番号を実際に使用する必要があります。

+0

これは私が使用するアプローチですが、書くのは面倒です。 Windowsでも使えますが、スクリプトは少し異なります。特別なプログラミング言語の必要はありません。私は正直なところ、基本的な質問をしているユーザはコードなしでPythonスクリプトを記述できるとは思っていません。 –

+0

ファイルアプローチには、入力ファイルをアーカイブできるという利点があります。私は、一握りのパラメータ以上のものがあれば、一般的にそれを使用します。 – agentp

+0

ありがとうございました。私がfortran 77を主張したのは、私の同僚がfortran 77ですでに書いたコードを使用しているからです。プログラマーはあまりありませんが、fortran 77のコードをより現代的なものに単純に変更する方法はありますか? –

0

コードに変更する場合は、再コンパイルする必要があります。

プログラムの複雑さはわかりませんが、通常、ユーザーインターフェイスまたはファイルから値を読み込むようにプログラムを書き込むことをお勧めします。

CHECK_COMMAND_ARGUMENTまたはNamelistsをチェックしてください。

ただし、毎回パスを再コンパイルする場合は、プリプロセッサを使用してコードの特定の部分を設定することができます。

このサンプルコードを参照してください:(

 PROGRAM area 
     IMPLICIT NONE 
     PRINT *, "area of circle with radius ", RADIUS, " is ", 
    &   3.15159 * RADIUS**2 
     END PROGRAM area 

プリプロセッサを使用するには、次のいずれかを明示的に(gfortran -cppまたは例えばifort -fpp)それを行うには、コンパイラに指示する必要があります。または、首都.Fに拡張子を変更することができます最新のFortranの場合は.F90)、デフォルトでプリプロセッサを有効にします。私はパラメータの単一のセットを操作することを期待コードにパラメトリック解析を実行するために持っていたケースでは、私は大きなを生成するために、Jinja2のテンプレートライブラリを使用してPythonで小さなスクリプトを書いた

$ gfortran -D RADIUS=2 area.F -o area 
$ ./area 
area of circle with radius   2 is 12.6063604 
$ gfortran -D RADIUS=20 area.F -o area 
$ ./area 
area of circle with radius   20 is 1260.63599 
+0

私は今、プリプロセッサに関する多くのプログラミング経験なしで人々に伝えることに関する第二の考えを持っています...彼らは奇妙な効果を持つことができます... – chw21

+5

プログラムのそれぞれの異なる実行のために再コンパイルする人々を教える、エフェクト* ... –

0

入力ファイルの数。どの入力ファイルがどの入力順列に対応しているのかを簡単に判断し、結果の後処理を支援する命名規則を選択します。 Python & Jinja2の特定の使用法は、入力ジェネレータスクリプトを編集せずに生成されたファイルを調整できるように、入力生成スクリプトの外にテキストテンプレートを置くことほど重要ではありません。入力テキストファイルを効率的に生成できる、成熟したシンプルなWebテンプレートシステムがたくさんあります。

入力パラメータとファイル名の相互参照は、データ構造の配列(つまり、ハッシュまたはdict)へのインデックスと同じくらい簡単です。私はより意味のある何かを使用し、生成された入力に説明的なコメントを追加しようとします(入力フォーマットがコメントを許可すると仮定します...)

私の場合は、1か月間のQAサイクルを経ることなく再コンパイルできないコードを使用している可能性があります。パラメトリックなバリエーションコードを別のスクリプトとして記述する方が安価です私のFortranコード。

私がPythonでパラメトリック解析コードを書いている他の理由は、Fortranで複雑な入力処理を書くよりはるかに簡単だからです。直線的、対数的、またはその他のバリエーションパターン(例えばチェビシェフノード)を生成するのにnumpyを使用できることは、Fortranでそれをしようとするよりもずっと簡単です。

標準の免責事項:私の動作環境とユースケースはおそらくあなたとは非常に異なるため、この方法は適切ではない可能性があります。私はそれがあなたの環境に応じていくつかの利点を持つオプションであることを指摘しています。

1

あなたの代わりにiargcgetargを使用する必要があり、古代のコンパイラのコマンドライン引数のアプローチ

implicit none 
    real r 
    character*30 arg 
    integer ios 
    if(command_argument_count().eq.0)then 
! default for no argument 
    r=1. 
    else 
    call get_command_argument(1,arg) 
    read(arg,*,iostat=ios)r 
    if(ios.ne.0)then 
     write(*,*)'error expected number arg got ',arg 
     stop 
    endif 
    endif 
    write(*,*)r 
    end 

ノート。純粋主義者はこれらが非標準のf77であることに注意しますが、多くのコンパイラでは一般的に利用可能です。引数のリストをループに

典型的なPythonスクリプト:コースの

import os 
for r in (1.2,6.6): os.system('fortran_program %g'%r) 

あなたが慣れているものは何でもスクリプト言語を使用する必要があります。私は必然的にスクリプトで計算を終わらせているように見えるので、「高水準」の言語が好きです。

関連する問題