2012-05-12

自動配列の割付で謎の segmentation fault @ ifort

[2012-05-12追記] これたぶん結局 ulimit -s で解決した話だったと思うので、http://naturesflyers.blogspot.jp/2009/12/ulimit.html も参照。現状、-heap-arrays なんて使ってないし、全部 allocatable に置き換えたりもしてないので。

---
   real(8) :: pt(1:xyz+3, -1:i_max+1, -1:j_max+1, 0:k_max+1)

っていう自動配列の割付がなぜかうまく行かず。 i_max, j_max, k_max を他のに変えるとうまく行く。こいつの上下でも、i_max, j_max, k_max という変数を使った割付はしまくっているので、意味不明。さらに謎なのが、g95 で -ftrace=full -fbounds-check を付けても、問題なく通るという事実。ちなみに ifort 10 でも 11 でも同様。

結局、下記を参考に、 -heap-arrays オプションを付けると通った。

http://wind.geophys.tohoku.ac.jp/~sawada/linux/intel.html
http://wind.geophys.tohoku.ac.jp/nonhydro/toolbox/How2NhmV2R0_ifort.txt

これがなんなのかだが、
-heap-arrays[-]
自動配列および一時的な計算用に作成される配列を、スタックではなくヒープ上に割り当てるように指示します。
とのこと (from  http://www.xlsoft.com/jp/products/intel/compilers/fcl/10.1/Release_Notes.htm )。
「あ゛?」って感じで、正直、ヒープ領域とスタック領域って聞いたことはあるけど何がどう違うのってのはよくわからん。

 とりあえず、気象庁コーディングルールに(やっぱり)載ってたのを発見:
自動配列はメモリのスタック領域を使用する場合が多く、ヒープ領域を使用す る場合が多いallocatable 配列より自動配列の方が割付を高速に行えることが多 い。しかし、使用可能なスタックのサイズに制限がある場合があり、自動配列で 使用できるメモリが制限される場合がある。(OS・コンパイラによる。)
まさにこれじゃね?どうも「使用可能なスタックのサイズ」ってやつの限界まで自動配列で割り付けちまったらしい。g95 ではその「サイズ」ってのが違うんだな(?)。

こちらのページにも同じことが・・・(正しくは「わかりずらい」→「わかりづらい」だがそんなことはどうでもいい)
このバグは実行時に非常に分かりずらい形で現れるため,codingの際にルールとしてallocatableで宣言するようにした方がいいと思う.
from: http://locs.bw.nitech.ac.jp/~kobayashi/programming.html

そっか、allocatable の方が結局いいのか・・・ orz

お、そしてここのリンク先でやっとスタックとヒープがわかりそうな予感(今から読む
http://asp.mi.hama-med.ac.jp/comp-basic/memory/

----
うーん。
  a. -heap-arrays で押し通す
  b. allocatable + de/allocate に(なるべく)変える
・・・こんなのおれのコーディングミスとは言えないんだからコンパイル側で何とかしてほしいよなぁ。ってことでとりあえず a. で。結果変わったり遅くなったりしたら泣けるが・・・。

と思ったけど、やっぱ allocatable にしよう。ただし、気象庁コーディングルールに従って、「値がどんどん変わる変数については、global にはせず、引数で渡してゆく」のは徹底しよう。

----
あと一般に参考になるサイトを追加っつーかメモ:

http://www.nag-j.co.jp/fortran/index.html
http://jujuohoh.hp.infoseek.co.jp/tips/index.html

No comments: