自由形式
1行には132文字までしか書けない
大文字・小文字
Fortranに大文字小文字の区別はない。
関数・サブルーチン
関数はそれ自体が変数を返す。ineger a = func()
ってできるってこと。
サブルーチンは引数に値を代入することで値を返す。サブルーチンが変数を直接返すわけではない。だから上記のようにはできない。
関数
定義
型名 function 関数名([引数,,...])
引数の定義
処理
end [function]
もしくは
function 関数名([引数,,...])
引数の定義(ここに関数の型名も記述)
処理
end [function]
呼び出し
x = myfunc(a,b,c)
※ただし、呼び出し元のプログラムに関数名と同じ変数が同じ型で定義されてなければならない。
サブルーチン
定義
引数ははじめは普通に使って、2行目で色々定義する
subroutine サブルーチン名([引数,,...])
引数の定義
処理
end [subroutine]
呼び出し
call mysub(a,b,c)
getarg,iargc
コマンドライン引数にアクセスするためのサブルーチン(getarg)と関数(iargc)
ここではgetargについて書く。iargはググってhttps://docs.oracle.com/cd/E19205-01/820-1201/aetdg/index.html
こうやって呼び出す。
call getarg(k,arg)
kは引数のint番号。0がコマンド名に相当し、1つ目2つ目...の引数が1,2...となる。
argにその引数が出力される。
write,print,read
http://www.nag-j.co.jp/fortran/FI_14.html
これ見てがんばって
readでx使うとその分スキップって扱いっぽい
フォーマットを指定して代入したい時もreadが便利
空白削除
trim(adjustl([string変数なにか]))
trimは後ろの空白を、adjustlは前の空白を消す。
open
open([装置番号],file=[file],form=[form],access=[access],recl=[],status=[],iostat=[])
fileまでは普通とする。
formはフォーマットを決められる。
access='direct'は直接探査法式を示す。どのような順番でも読み取ることができる。ただし、すべてのレコードが固定長である必要がある。unformatted,directにするとバイナリ形式での読み込みになる。
reclはひとつのレコードのバイト長を示す。バイト数×縦ピクセル数×横ピクセル数
みたいな感じで使用。
statusは元のファイルがあったらどうするかを決める。
iostatはi/oエラー発生したらなんて変数に状況を書きこむかを定める。
- 停留読み取りの際に記録終了条件が発生した場合,値 -2。
- ファイル終了条件が発生した場合,値 -1。
- 通常の完了の場合,値 0 (エラー状態,ファイル終了条件,記録終了条件のいずれでもない場合)。
- エラー状態が発生した場合,正の整数値。
omp
並列計算をするためのもの。
いろいろやるには!$ use omp_lib
が必要。
!$omp parallel
!ここが並列化される
!$omp end parallel
並列化されたところは全部のスレッドで同じ処理が行われるので注意。
さらに、同じ処理は、同じメモリを参照するために、変数が随時置き換えられてしまうのでそれにも注意。
それされたくなければ、配列にしてi(omp_get_thread_num)
ってするとか必要。
か、thread private
(後述)
また、並列部に
!$omp do
!$omp end do
ってのを入れるとその部分のdoは並列にThreadに分割してやってくれる
まとめると
!$omp parallel
!$omp do
do なんとか〜
!$omp end do
!$omp end parallel
って書く。
!$OMP PARALLEL DO
DO なんとか~
!$OMP END PARALLEL DO
でも同じ。
THREAD PRIVATE
並列処理すると、同じ変数を別のスレッドで同時に使うことになる。
そうすると、スレッド同士で変数の上書きあいが行われる。
それを回避するためにこれを使う。
!$ SAVE ix, jx, jy, imy
!$OMP THREADPRIVATE ( ix, jx, jy, imy)
こんなふうにすればここに挙げた変数はスレッドごとに置かれる。
ただし、ループの繰り返し制御変数はそもそも連れっどごとに分けて配分されるので入れてはいけない。
ただし配列はこれだとダメ
要素数を定義してからじゃないといけないので,allocate後,実際のループの箇所で以下のようにする
!$OMP PARALLEL DO private(!配列名(カッコはなし。コロンもなし。)!)