PGIコンパイラと inline 関数の衝突

先日の dSFMT の話の続き。
dSFMT をテキトーに C++ のクラスに書き換えてカプセル化して使っているんだが、 gcc では通るコードが PGI のコンパイラではエラーになるというもの。

どうでもいいけど PGI のコンパイラはエラーが判りにくすぎる。表示してる行番号が読まれるはずのない if def の中だったりとか(CPP 通した後の行数だったりするのか?)。

一件は、 pgCC の version を上げたら解決した(7.1-4 → 7.1-6)。 type mismatch って、いや、型はちゃんと合ってるし。よく判らん。

PGCC-W-0277-Cannot inline function _mm_load_si128 - data type mismatch (../shunlib/dSFMT.cc: 320)
PGCC-W-0277-Cannot inline function _mm_load_si128 - data type mismatch (../shunlib/dSFMT.cc: 320)
PGCC-W-0277-Cannot inline function _mm_xor_si128 - data type mismatch (../shunlib/dSFMT.cc: 320)
PGCC-W-0277-Cannot inline function _mm_or_si128 - data type mismatch (../shunlib/dSFMT.cc: 320)
PGCC-W-0095-Type cast required for this conversion (../shunlib/dSFMT.cc: 320)
PGCC-S-0094-Illegal type conversion required (../shunlib/dSFMT.cc: 320)
PGCC-W-0277-Cannot inline function _mm_xor_si128 - data type mismatch (../shunlib/dSFMT.cc: 320)
PGCC-W-0277-Cannot inline function _mm_or_si128 - data type mismatch (../shunlib/dSFMT.cc: 320)
PGCC/x86 Linux 7.1-4: compilation completed with severe errors

解決しなかったのはこういうこと。
class A のメンバ関数 funcA を inline にしたとする。 A::funcA() は header file A.h で定義される。 class A を継承した class B を作る。 head file B.h は A.h を include している。で、この B.h をメインプログラム側で include する。 compile 単位は、 A.cc, B.cc, main.cc の3つになって、最後に link するときになって A.o, B.o, main.o にそれぞれ A::funcA() がありますよ、となる。

で、 link 時に重複してるのは消すのが普通の動作だと思ってるんだがなぁ。てゆーか、 gcc ではちゃんと通っている訳だし。衝突しているので link できないとか云うのが PGI 。どうもよく判らん。 inline の中がバキバキ inline 化されてるから、 inline の段数の違うものになっているんだろうか?いやそれとも、ちゃんと inline 展開されてたら obj file の段階で関数の形保ってないんではないかな?とか。 IPA なんて頑張らせるのが駄目なのか?いや最適化外しても衝突するがとかともかく謎。

IPA fatal error: function 'genrand_open_open__11dSFMTRandomFv' multiply defined in: rmc2.cc
IPA fatal error: function 'genrand_open_open__11dSFMTRandomFv' multiply defined in: ../shunlib/dSFMT.cc
IPA fatal error: function 'genrand_open_open__11dSFMTRandomFv' multiply defined in: ../shunlib/rnd.cc

当座の答えは、 -Wl,--allow-multiple-definition で linker を黙らせる、というもの。それでも IPA がコケてるんだがな・・・

ほかにも、学生の頃作った怪しい class 食わすと、何故か Iterator でエラーになる・・・。てゆーか、その class は iterator 使ってねーし・・・。

  1. "/opt/pgi/linux86-64/7.1-6/include/CC/stl/_iterator_base.h", line 95: error:
  2. name followed by "::""std::iterator_traits<_Iterator> [with _Iterator=double]"
  3. at line 51 of
  4. "/opt/pgi/linux86-64/7.1-6/include/CC/stl/_iterator.h""std::reverse_iterator<_Iterator> [with
  5. _Iterator=double]" at line 69 of "vec.h"

18:32:00 - 22.04.08 - kuroyagi - その他雑記 - 6774x