fortranでfftw
実行環境
macOS Big Sur ver 11.4
iMac(24-inch, M1, 2021)
チップ:apple M1
gcc version 13.1.0 (Homebrew GCC 13.1.0)
簡潔さのため、homebrewはすでにinstall済みとして話を進めていきます。
fftwとは
fftwは、フーリエ変換のライブラリの一つ。中身はCで書かれてるようです。
詳しくは本家をご参照ください。
私は、fortran用のfftライブラリを探している中で最初に見つけたものです。
特に、これといって選んだ理由はないです。
要約
詳しくは後述しますが、gfortranでfftwライブラリを使ったファイルを実行しようとしたところ、下記のようなエラーが出ました。
実行文
gfortran -o fftw3_test.out fftw3_test.f90 -I/usr/local/include -L/usr/local/lib -lfftw3
エラー
Undefined symbols for architecture arm64:
"_dfftw_destroy_plan_", referenced from:
_MAIN__ in ccwOjQZW.o
"_dfftw_execute_dft_", referenced from:
_MAIN__ in ccwOjQZW.o
"_dfftw_plan_dft_1d_", referenced from:
_MAIN__ in ccwOjQZW.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
解決策として、サイトから直接落とすのではなくbrewを使って/opt内に改めてダウンロードし直しました。
arch -arm64 brew install fftw
その結果
Pruned 0 symbolic links and 5 directories from /opt/homebrew
となり、/opt下にダウンロードされ直されました。(finderからも念の為確認)
その後、
実行文を
gfortran -o fftw3_test.out fftw3_test.f90 -I/opt/homebrew/include -L/opt/homebrew/lib -lfftw3
と書き直して、実行したところうまくいきました。
問題と対応
以下今回の対応を詳しく書いていますが、ただの自分用の備忘録なので気になる方はみてください。
考察のところにある疑問に答えてくださる方がいれば幸いです。
ダウンロードからmake install
最初は上記のurl先から圧縮ファイルをダウンロードして以下のサイトを参考にインストールを行いました。
Downloadsディレクトリ下にあった圧縮ファイルを解凍したのち、以下の設定でインストールし、localディレクトリにインストールしました。
User@iMac Downloads % . /configure --prefix=/usr/local/fftw3 CC=gcc MPICC=mpicc F77=gfortran --enable-mpi --enable-threads
User@iMac Downloads % make
User@iMac Downloads % sudo make install
因みに、今回実行した時にlocal内には他にファイルはありませんでした。
以下のサイトでは、
仮にlocal内に他のファイルが既存の場合、デフォルトの設定で全てのファイルがlocalディレクトリ内に保存されるため、その影響かも?という感じの内容が書かれていました。(私の英語理解が間違ってなければ、、、)
プログラム実行
下記のサイトを参考にfftのテストプログラムを回してみた(要約と同じ流れ)。
gfortran -o fftw3_test.out fftw3_test.f90 -I/usr/local/include -L/usr/local/lib -lfftw3
エラー
Undefined symbols for architecture arm64:
"_dfftw_destroy_plan_", referenced from:
_MAIN__ in ccwOjQZW.o
"_dfftw_execute_dft_", referenced from:
_MAIN__ in ccwOjQZW.o
"_dfftw_plan_dft_1d_", referenced from:
_MAIN__ in ccwOjQZW.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
エラーの内容
テストプログラム中の関数_MAIN__ in ccwOjQZW.o
で使用している_dfftw_destroy_plan_
がエラーを起こしているようです。
さらに実行を一度に行うのではなく、段階的にオブジェクトファイルの生成とリンクを行なったところ、コンパイル自体は通りました(当たり前ですが)。しかしリンク時に同様のエラーが生じました。
対応1
一応、Downloadsディレクトリ下でそのまま行ったのが悪かったなと思い、localに移動させて同様の処理を行いましたが、解決しませんでした。
対応2
次に、サイトから直接落とすのではなくbrewを使って/opt内に改めてダウンロードし直しました。
arch -arm64 brew install fftw
その結果
Pruned 0 symbolic links and 5 directories from /opt/homebrew
となり、/opt下にダウンロードされ直されました。(finderからも念の為確認)
その後、
実行文を
gfortran -o fftw3_test.out fftw3_test.f90 -I/opt/homebrew/include -L/opt/homebrew/lib -lfftw3
と書き直して、実行したところうまくいきました。
疑問
なぜうまくいかなかったのか?
最初の方法でうまくいかなった理由が釈然としない。参考記事の中には2020年後のものもあったのでM1チップ環境下のものもありそうですが、明言されていなかったのでなんとも言えませんね。
iMacとMacBookでの違い
MacBookでもbrewを使ってfftwをインストールしてみました。
すると、
Pruned 0 symbolic links and 5 directories from /usr/local
となり、iMacとの結果と異なり、元々の方法で目標であった/local内に保存されました。
詳しい原因を探る元気は今はないので今度詳しく調べてます。
一応予想としては、随分前にMacBookは.zshrcをいじったのことか、MacBookの方にはlocalに既存のファイルがあったことぐらいしかないです。brewのバージョンは同じでした。
参考