「n十年前、学生時代に現場でカラダで覚えたFortranだが、どうも最近の進展はよくわかんねぇんだょなぁ」という、ある程度Fortranを読み書きできるんだけれどModern Fortranなどと呼ばれている最近の状況に乗り遅れている人がキャッチアップするために集めた情報。
正攻法で学ぶ
「こんな機能ないのかな?」「ネットの海を彷徨っていたら面白い情報を見つけた」という能動的に学習した事項
エラーから学ぶ
直面したエラーから、解決のためにいろいろ学んだ、ある種対処療法的な事項
異なる関数の引数がマッチしていないと怒られる(GCC 11.4.0)
Call MPI_BCAST(input_data,256,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr)
Call MPI_BCAST(sys_name,256,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr)
Call MPI_BCAST(dir_name,256,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr)
Call MPI_BCAST(DFT_option,32,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr)
Call MPI_BCAST(Band_option,1,MPI_LOGICAL,0,MPI_COMM_WORLD,ierr)
をopenmpi-5.0.3 + gcc-11.4.0
でビルドしようとすると以下のようなエラーが出る。
Initialization.f90:28:17:
24 | Call MPI_BCAST(input_data,256,MPI_CHARACTER,0,MPI_COMM_WORLD,ierr)
| 2
......
28 | Call MPI_BCAST(Band_option,1,MPI_LOGICAL,0,MPI_COMM_WORLD,ierr)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (LOGICAL(4)/CHARACTER(*)).
引数のミスマッチが、異なる関数callの引数にされていて、わけわかめ。(MPIのAPI的には、同一callのMPI_BCAST
ルーチンの第一引数の型と三つ目の変数の型説明が一致していれば良い。したがって、そもそも異なるcallに対してこれらが一致している必要はないのでエラーとして表示されるのが不可解。)
この解決策がlinux - fortran: Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)) - Stack Overflowに書いてあって、ここから抜粋すると
・Tells gfortran to ignore this concerns with option -fallow-argument-mismatch.
・Use modern fortran interface (use mpi instead of include mpif.h) I chose the latter.
となる。正直前者は副作用が怖いので、後者の方法を試してみたら問題は解決した。
戯言・感想
新しいGCCでは型チェックがstrictになったので、こう言った事例が現れるようになった みたいな記載がちらほら。実際、同じコードをgcc-9.4.0
でビルドしたら何もエラーは出なかった。
chatgpt先生に尋ねたものの的をいた答えが返ってこず(2024/09/12時点)、結局この解決方法はgoogleでエラーをコピペして検索している過程で見つけた。
ちなみに、上記のコードはエラーを再現するために最低限必要な部分の抜粋で、実際は他のMPI_BCAST
関数とも組み合わさって、何行もエラーが出てきた。一方で、必ずしも全てのMPI_BCAST
のcallが引っかかっている訳ではなくて、理屈はよくわからなかった。
当該環境では、自身で/opt
以下に入れた環境をEnvironmental Moduleでloadしたもの。これが遺留で、ヘッダーを探しに行っているフォルダの設定が間違っているのかと思ったけれど、mpif90 --showme
で調べたら正しそうなフォルダが-I
以下に書かれていたので、その可能性は薄いな というような考察はした。