2008年7月16日

きちんとループで書いた方がいいのか…

配列をコピーするとき Fortran 90 では

a = b

のように変数のように書くことが出来ます(もちろん両方の変数の要素数が合っている必要がありますが…)。しかしながら配列の要素数が大きくなった時にセグメンテーションフォールトで落ちてしまった。試しに

a(1:ix,1:jx) = b(1:ix,1:jx)

としても当然同じ結果に。一度ループできちんと書いてみようということで

do j = 1, jx do i = 1, ix a(i,j) = b(i,j) end do end do

と書いたら無事に動いた。どうもスタックメモリの問題っぽいということで ulimit -s にてスタックサイズを大きくして一番最初のコードで実行してみたら動いた。う〜ん、汎用性を考えるときちんとループで書いた方がよいということかな。

投稿者 kato : 02:44 | コメント (0) | トラックバック

2008年6月19日

無制限ではないのか…

MM5 を MPI を用いて並列計算しているのですが最後まで計算出来ないようになってしまった。ログを見る限りスタックサイズの問題っぽい。ということで

ulimit -s unlimited

と無制限にしても相変わらず同じように落ちる。で、いろいろ調べていたらどうも unlimited は無制限といいつつも実際にはそうでないらしい。ということで明示的に指定する必要があるっぽい。ということで

ulimit -s 16379

で現在テスト中。なお、スタックサイズは 1024 の倍数で指定する必要があるらしい。

参考 URL:
PGI guide to 64-bit MM5

投稿者 kato : 03:57 | コメント (0) | トラックバック

2007年11月21日

Linux x86_64 で netcdf-perl

64bit Linux 環境で netcdf-perl をコンパイルしようとしたらリンクの段階で怒られた。どうもメッセージを見ると netCDF ライブラリを -fPIC オプションをつけてコンパイルしなさいとのこと。ということで netCDF ライブラリを CFLAGS=-fPIC を configure の時に追加してコンパイル、インストール後 netcdf-perl をコンパイルしたら無事に終了した。

う〜ん、いろいろ 64bit にすると問題があるんだなぁ。 個人的な環境はまだ 64bit ではないのですが、今後を考えるとテスト環境だけでも用意しておく必要があるな…


投稿者 kato : 09:40 | コメント (0) | トラックバック

2007年7月11日

可変長の文字型処理

Fortran で任意のバイナリを扱うために、BufferSize 文字の文字型でキャッシュして transfer 関数を用いて値に変換するということは前のエントリで書きました。その際、バッファサイズは外部から与えたいので可変長で文字型を定義する必要があります。しかしんがら Fortran において文字型は最初に定義されてしまうという問題があります。そこで

character, dimension(:), allocatable :: Buffer allocate( Buffer(BufferSize) )

のように1文字の文字型配列を allocatble で定義しまし。これで最初うまく行くと思っていたのですが、例えば

Buffer(1:5) = 'abcde'

のように文字列 "abcde" を代入してみると結果は Buffer(1) 〜 Buffer(5) すべてに "a" が入る。これは「1文字の文字型の配列」なので、上の代入文の時に2文字目以降は無視されるということのようです。

次の手を考えねば…といいつつ現在の私の知識ではよく分からんと行き詰まっていたのですが、試しにこのまま read 文でデータを呼んでみたら何事もなかったように読んでくれた。ifort でも pgf90 でも問題なく動いたのできっと大丈夫でしょう。

投稿者 kato : 02:56 | コメント (0) | トラックバック

2007年7月10日

いい方法はないのかしら

Fortran で不定長の単純バイナリを読むのはとても大変。昔は C の fseek, fread に対応する Fortran 用の関数を C で作成してライブラリ化していたのですが、どの環境でも動作することを考えたりするとやっぱり Fortran で閉じていた方がいいなぁ。ということで頑張ってみた。

アイディアは単純。ファイルを直接探査で呼び、レコードサイズを BufferSize だけの文字型で定義する。つまり以下の用に読む。

integer, parameter :: BufferSize = 1024 character(len=BufferSize) :: Buffer open( 11, file=filename, access='direct', recl=BufferSize ) ... read(11,rec=irec) Buffer ...

そして必要の範囲のデータを切り出して型変換を主に transfer 関数を用いて行い、Buffer の最後まで来たら次のバッファを読むという戦略。ちょっと面倒なのと速度的にどうかと思うものの、データ変換くらいならば時間はあまり気にしなくてもいいかと自分に言い聞かせます。

一見うまくいったようなのですが、セグメントエラーで落ちる場合が出ました。最初は読み込み部分が問題とは思わず、ポインタ関連だと思い込みその周りをずっとチェックしていました。ところがあることをきっかけにそうではないことに気づきました。

エラーの原因は分かってみると単純で以下の通りでした。適当なバッファサイズ(上では 1024バイト)で呼んでいくと最後のレコードが必ずしも、というよりもほとんどの場合、バッファサイズよりも小さいサイズを読むことになります。その結果、アドレス空間に異常が生じてセグメントエラーになるということでした。ということで、バッファサイズはファイルサイズの約数でないとダメだということです。ファイルサイズが奇数の場合はどうしよう ^^;

ちなみにきっかけですが、コンパイラを ifort から pgf90 に変えてみた事でした。ifort の場合、レコードサイズと読み込むデータサイズが異なっていても読み込んでしまっていたのに対し、pgf90 ではその段階でエラーが出ました。それでようやく気がつきました。やっぱりどの環境でも動くというのはかなり気をつけないと難しいものだと改めて実感しました。

投稿者 kato : 02:21 | コメント (0) | トラックバック

2007年6月28日

Intel Fortran for Linux 10.0

が出たらしい。暇を見てインストールしてみよう。

投稿者 kato : 01:08 | コメント (0) | トラックバック

2007年3月11日

共有ライブラリの生成

今作っている解析パッケージのデータ読み込み部分をプラグイン対応にしたいので共有ライブラリの作成方法を調べたことの覚え書き。コンパイル時に

$ ifort -fpic -c hoge,f90

のように -fpic オプションをつけるだけのようだ。そしてライブラリ作成時には

$ ifort -shared -o libhoge.so hoge.o

のように -shared オプションをつければよいらしい。オブジェクトが複数あっても同じ。

実行時に環境変数 LD_LIBRARY_PATH を共有ライブラリのある場所にもパスを通し忘れることのないようにすることが注意すべき所かな。ま、でも実際に使うのかなぁ… :-)

投稿者 kato : 19:29 | コメント (0) | トラックバック

2007年1月15日

Fortran に代わる新プログラム言語 Fortress

サンが Fortran に代わる新プログラム言語 Fortress を開発しているようです。並列化を意識した実装になっているようです。でも、普及するのかなぁ…。とりあえず Fortress のプロジェクトホームにいって仕様の PDF をダウンロードしたので、暇な時に読んでみよう。

参考 URL:
サン、Fortranに代わる新プログラミング言語をオープンソースに (ZDNet Japan)
fortress プロジェクトホーム
Sun、新プログラミング言語Fortressをオープンソースとして公開 (slashdot.jp)

投稿者 kato : 22:50 | コメント (0) | トラックバック

 1  |  2  | All pages