コンパイル/リンク/プログラム実行時の問題に対するFAQ

 本ページは、PGIコンパイラを使用して、コンパイル/リンク/プログラム実行時の問題に対する FAQ のページです。
© 株式会社ソフテック

PGI コンパイル/リンク/プログラム実行時の問題に対するFAQ

  1. PGI コンパイラで作成した実行モジュールは他のマシンでも実行できますか
  2. PGI コンパイラにおける、動的リンク、静的リンクとはどのような意味でしょうか
  3. 1GB を越えるメモリを使用する Fortran プログラムを実行できますか (32bit 版 使用時)
  4. 2GB を越えるメモリを使用する C/Fortran プログラムを実行できますか (64bit 版 使用時)
  5. Linux kernel 2.4 で対応している Large File System(2GB 以上のファイル操作)に関して、対応していますか
  6. コンパイル時に以下のようなエラーが出てしまいます。バグでしょうか
  7. コンパイル・オプションの -fastsse 使用して Makefile により実行モジュールを作成しようとすると、リンク時に以下のような "__mth_i_xxx" のエラー出ます
  8. 自動並列化オプション -Mconcur を指定して、実行モジュールを作成しようとすると、リンク時に、以下のような _mp_???? 等の未定義関数が発生します
  9. 内部手続き間のグローバル最適化のオプション -Mipa を使用する際の留意点はありますか
  10. リンク時に、以下のような ___rouent 等の未定義関数があると言うメッセージが出ます
  11. リンカーに未定義の関数参照を無視してリンクするように指示するオプション/フラグはありませんか (Linux)
  12. リンケージ・マップを出力する方法を教えてください (Linux)
  13. LAPACK を使用する際のリンク・オプションを教えてください
  14. Sun, SGI 等の UNIX システムで実行した結果と PGI での計算結果が微妙に異なるのですが、どのような原因が考えられますか
  15. Fortran プログラムの終了時に出力される FORTRAN STOP を抑制することができますか
  16. Fortranプログラムが何らかの理由(例えばエラーや人為的に終了させるなど)で途中でストップしたとき、その時点までの結果がファイルに書き出されるようにするにはどうすればよいのでしょうか?
  17. Intel Fortran、Compaq Fortran のような「環境変数」により、ユニット機番とファイル名を連結する方法について
  18. Fedora Core 4 等においてデフォルトで SELinux (セキュアLinux) が動作しているシステムで、PGI ユーティリティの pgdbg、pgprof が起動時に Java のエラーで落ちます
  19. RedHat Enterprise 4 上で、PGI ユーティリティの pgdbg、pgprof を起動する際にlibXp.so.6 がオープンできないと言うエラーで落ちます
  20. 開発中のプログラムが突然、segmentation fault で終了します。どこの部分で終了したか調べる方法はありますか?
  21. リリース PGI 6.1 を /usr/pgi 配下にインストールしました。過去のバージョンの PGI 5.2、6.0 ソフトウェアも、/usr/pgi 配下に削除せず残しています。デフォルト・バージョンは PGI 6.1 の状態で、過去のバージョンを使用する方法はありますか
  22. PGI 6.1 の PGDBG/PGPROF を使用する際、Java Runtime Environment が 1.5.0_04 以上を必要とされると言うメッセージが出ます
  23. SUSE 10.0 (64bit) 上で PGI 6.0-8 を使用しています。コンパイルオプションに -Mipa を使用すると、リンク時にエラーが生じます。この対処法を教えてください
  24. PGI 6.1 をインストールし、コンパイル後実行した際に、 GLIBC_2.2.5 not defined と言うエラーが生じます。この対処法を教えてください
  25. PGI コンパイラで生成したオブジェクト・ファイルの PGI バージョンに依存した互換性について教えてください
  26. Linux のアップデートにより GCC/Glibc のバージョンが変更された後、リンク時に GNU 関連のライブラリがリンクできず、実行モジュールの生成ができません
  27. PGI 7.1 からバンドルされた MPICHライブラリや、MPIプログラム用のツールの使用方法を教えてください
  28. PGI Workstation ライセンスで生成した実行モジュールの使用可能な並列スレッド数の上限値は、バージョンによって変更されていますか
  29. PGI C++コンパイラ(pgCC or pgcpp)環境において、C言語の ISO/IEC C99 規約で定義されている関数を組み込む方法を教えて下さい
  30. PGI 11.0 (PGI 2011)以降の PGFORTRAN コンパイラで実行モジュールを作成し実行すると、実行終了時に、ieee_inexact is signaling と言う警告メッセージが出ます。この意味とこのメッセージを抑止する方法を教えて下さい
  31. Sandybridge プロセッサを搭載した OS X 10.7 (Lion) 上で PGI 11.x (PGI 2011) を使用してコンパイルすると、no such instruction: `vzeroupper' と言うエラーメッセージが出ます
  32. PGI CDK 12.2 以降で、CDK ソフトウェアにバンドルされた MPICH2 の mpiexec を実行できません。エラーメッセージは、mpiexec: error while loading shared libraries: libpgmp.so: cannot open shared object file: No such file or directory と言うものです
  33. PGI 2016 (16.3)以降、Windows版は C++ コンパイラの提供が終了しました。旧バージョン PGI 15.10 の C++ コンパイラを使用できますか? その方法を教えて下さい。
 

コンパイル/リンク/プログラム実行時の問題への回答

Question  1. PGI コンパイラで作成した実行モジュールは他のマシンでも実行できますか?

Answer

実行できます。他のマシンで実行するための技術的な詳細情報は、こちらのページをご覧ください。

  • コンパイルオプションで特定の CPU に特化した最適化オプション("-tp"、"-Mvect=sse"オプション等)を指定した場合、同じ CPU アーキテクチャ(動作周波数は変わっても構いません)を搭載したマシンでのみ動作致します。 どのマシンでも実行できるような汎用的な実行バイナリファイルを作成したい場合は、"-tp p6" オプションを使用して、他のマシンの CPU ターゲットに合ったクロス・コンパイリングを行ってください。
  • Release 4.1 以降をご使用の際は、動的ライブラリ libpgc.so が必要となります。 また、"-Mconcur"、"-mp"オプション等、自動並列化オプションを指定した場合、動的ライブラリ libpgthread.so および libpgc.so が必要となります。 実行モジュールを実行するマシンにおいて、$PGI/linux86/lib ディレクトリに動的ライブラリをコピーして頂くか($PGI/linux86/lib ディレクトリが NFS 等で共有されていて、実行するマシンから参照できる場合はコピーの必要はございません)、環境変数 LD_LIBRARY_PATH で指定されたディレクトリに動的ライブラリをコピーして下さい。 その他の方法としては、コンパイル時に静的ライブラリ(拡張子.a ファイル)を使用して静的リンクする方法がございます。その際は、自動並列化オプションに加えて、"-Wl,-Bstatic" オプションを加えてコンパイルして下さい。この方法を用いた場合は、動的ライブラリのコピーは必要ございませんが、動的ライブラリを用いる場合に比べて、実行バイナリのサイズが大きくなります。

Question  2. PGI コンパイラにおける、動的リンク、静的リンクとはどのような意味でしょうか

Answer

ユーザプログラムをコンパイルし、実行モジュールを作成する際にインクルードするライブラリのリンク方法を指します。例えば、ユーザプログラム中にスレッド・ライブラリを使用することが明示されている場合、動的リンクの場合は、スレッド・ライブラリを使用する時点でライブラリが読み込まれるようになります。逆に静的リンクの場合は、ユーザプログラム中のスレッド・ライブラリ使用部分に、コンパイル時にスレッド・ライブラリが埋め込まれます。一般に、静的リンクで必要なライブラリ(static library) の名前は、一般に libxxx.a の形式 (.a) です。それに対して、以下で説明する動的リンクで必要なライブラリの名前は、一般に、libxxx.so の形式で、dynamic shared library と言われております。参考情報として、こちらのページをご覧ください。

動的リンクは、必要なライブラリを使用する時点でリンクするため、実行バイナリファイルサイズを小さくすることができ、使用メモリ量も減らすことが可能です。PGI コンパイラで生成される実行モジュールは、動的リンクを暗黙に行ないます。ただし動的リンクを行なった場合(これはデフォルトです)、作成された実行バイナリファイルを他のマシンで実行できない問題や、1 プロセスあたり、1GB 以上のメモリを使用できない問題が発生します。 この解決策の詳細についてはこちらのページをご覧ください。

Question  3. 1GB を越えるメモリを使用する Fortran プログラムを実行できますか (32bit版 使用時)

Answer

可能です(上限は 2GB程度です)。コンパイル・オプション "-Wl,-Bstatic" を用いて静的ライブラリを用いた実行モジュールを作成する必要があります(PGI 5.1 から同機能オプションである -Bstatic オプションが提供されました)。本オプションは、コンパイラが暗黙に用いる動的ライブラリを用いず、強制的に全て、スタティックなライブラリを用いた 静的リンクを行います。いわゆる、Linux上における 1GB の壁は、動的ライブラリをメモリマップ上に置くポイントが、1GB ポインタであることによる問題です。動的ライブラリを用いない静的リンクにしますと、この制約がなくなります。なお、1GBを越えるメモリ量を扱う Fortran プログラムを動かすためには、マシン自体にも十分なメモリ量(物理メモリ + swap メモリで 1GB 以上)を確保することも必要です(プログラムが必要とするメモリ量よりも、物理メモリ + swap メモリ量が少ないと正常に動作しません)。

また、32ビットLinux 上のメモリ管理仕様の一般的知見として、 mcmodel=small の場合、1 回当たりの malloc サイズが 128KB 以下の操作でスタックしていくメモリ使用総量の上限が 1GB まで、128KB 以上のスタックの集積総量の場合は、 2GB まで使用できると言う制約があります。

Question  4. 2GB を越えるメモリを使用する C/Fortran プログラムを実行できますか (64bit 版 使用時)

Answer

x86-64(AMD64) CPU 用の C、FORTRAN77、Fortran90 64bit コンパイラ release 5.2 以降で可能ですなお、2GB を越えるメモリ量を扱うプログラムを動かすためには、マシン自体にもプログラムに見合う十分な実メモリ量を確保することも必要です。 仮想メモリ+ Swap エリアを利用した実メモリ容量を超える大きなプログラムの実行は、性能が著しく低下します。ちなみに、2GB を超えるプログラムのコンパイル・オプションは次のとおりです。この詳細に関しては、技術情報(TIPS) のこちらのページでご覧ください。

pgf90 -mcmodel=medium -Mlarge_arrays  test.f
	あるいは、
pgf90 -tp {k8-64:p7-64} -mcmodel=medium -Mlarge_arrays test.f 

Question  5. Linux kernel 2.4 で対応している Large File System(2GB 以上のファイル操作)に関して、対応していますか

Answer

2GB 以上のファイルの取扱いに関しては、 PGI 5.0 以降の pgf77、pgf90 においてデフォルトで対応しております。リリース4以前の PGI コンパイラは 3.3 以降で、Large File System(2GB 以上のファイル操作)をサポートしております。リンク時に以下のオプションを付けて実行モジュールを作成してください。但し、いずれの場合も、Linux のファイルシステム機能が、2GB 以上のファイル操作が可能な実装状況が必要です。

   -Mlfs または -L$PGI/linux86/{Release_number}/liblf
              (一例:-L/usr/pgi/linux86/6.2/liblf)

Question  6. コンパイル時に以下のようなエラーが出てしまいます。バグでしょうか
:Assembler messages: :Error: no such instruction: `cvttsd2si -32(%ebp),%eax'

Answer

:Assembler messages: :Error: no such instruction: `cvttsd2si -32(%ebp),%eax'
"cvttsd2si" 命令は、Pentium 4 用の SSE2 命令です。Pentium 4 上で pgf77 コマンド等でコンパイルすると自動的にこの命令が埋め込まれる場合があり、SSE2 インストラクションを有していない Pentium 4 以外の下位 Pentium の CPU では正常に動作しません。また、Pentium 4 マシンでコンパイル時に cvtssd2si 関係のエラーが出る場合は、Pentium 4 用の命令を(カーネルが)認識できていない環境(古いRed Hat Linux の環境等)をお使い頂いていることが原因です。
"-tp p6" オプション (Pentium III まで対応の実行コードを生成します)をつけて頂ければ、上記エラーは解決できますが、Pentium 4 の SSE2 命令の機能が生かし切れなくなります(Pentium 4 で実行の際)。
 Red Hat のバージョンが、7.1 以降でしたら SSE 命令に対応しますので、 SSE 命令を活用する場合は、これらバージョンをお使い頂ければと思います。以下にRed Hat Linux の SSE 命令対応表を記します(PGI コンパイラ、リリース 3.2 以降は全ての SSE 命令に対応しています)。また、現在のプロセッサのハードウェアが備える SSE 機能対応表をこちらのページに用意しました。

Question  7. コンパイル・オプションの -fastsse 使用して Makefile により実行モジュールを作成しようとすると、リンク時に以下のような "__mth_i_xxx" のエラー出ます
  stream_d.o: In function `MAIN_':
  stream_d.o(.text+0x851): undefined reference to `__mth_i_idnintx'
  stream_d.o(.text+0x95f): undefined reference to `__mth_i_idnintx'
  stream_d.o: In function `realsize_':
  stream_d.o(.text+0x1afa): undefined reference to `__mth_i_dpowix'
  stream_d.o: In function `confuse_':
  stream_d.o(.text+0x25df): undefined reference to `__mth_i_dcosx'
  stream_d.o: In function `checktick_':
  stream_d.o(.text+0x269b): undefined reference to `__mth_i_idnintx'

Answer

-fastsse のオプションは、コンパイル時だけではなく、リンケージにおいてもオプションを付ける必要があります。リンク時にオプションの設定をしなかったために起こる問題です。Makefile 等で、コンパイル・フラグとリンク・フラグを分けて指定している場合、リンク・フラグにも -fastsse をつけてリンクを実行してください。

Question  8. 自動並列化オプション -Mconcur を指定して、実行モジュールを作成しようとすると、リンク時に、以下のような _mp_???? 等の未定義関数が発生します

Answer

 stream_d.o: In function `MAIN_':
 stream_d.o(.text+0x34a): undefined reference to `_mp_penter'
 stream_d.o(.text+0x34f): undefined reference to `_mp_ncpus'
 stream_d.o(.text+0x38c): undefined reference to `_mp_lcpu'
 stream_d.o(.text+0x427): undefined reference to `_mp_pexit'
 stream_d.o(.text+0x44f): undefined reference to `_mp_penter'
-Mconcur オプションは、コンパイル時だけではなく、リンケージにおいてもオプションを付ける必要があります。リンク時にオプションの設定をしなかったために起こる問題です。Makefile 等で、コンパイル・フラグとリンク・フラグを分けて指定している場合、リンク・フラグにも -Mconcur をつけてリンクを実行してください。

Question  9. 内部手続き間のグローバル最適化のオプション -Mipa を使用する際の留意点はありますか

Answer

PGI の内部手続き間のグローバル最適化は、リリース 5.2 以降、一度のコンパイル・リンク・フェーズで 1 パスで行いますが、その際、Makefile でコンパイル・フラグとリンク・フラグを分けて指定している場合、リンク・フラグにも必ず、-Mipa=fast,... をつけてリンクしてください。リンケージのフェーズで、最適化の情報をもとに実行モジュールがビルドされますので、リンク時にオプションを指定しなければ、このグローバル最適化はモジュールに反映されません。なお、IPA に関するコンパイル・リンク時のメッセージ情報を表示したい場合は、
-Minfo=ipa を指定してください。

(コンパイルし、*.o のオブジェクトを作成)
pgf90 -fastsse -Mipa=fast,inline -c -Minfo=ipa a1.f a2.f

(その後、リンクする)

Question  10. リンク時に、以下のような ___rouent 等の未定義関数があると言うメッセージが出ます

Answer

 Test.o: In function `MAIN_': 
 Test.o(.text+0x2d): undefined reference to `___rouent'
 Test.o(.text+0x121a): undefined reference to `___rouret'

これは、性能解析プロファイラ PGPROF 用のトレースファイルを作成するため、、コンパイラ・オプションに -Mprof を付加して実行モジュールを作成しようとした時に起こる現象です。-Mprof はコンパイル時と、リンク時の両方にオプションとして指定しなければなりません。リンク時にオプションの設定をしなかったために起こる問題です。Makefile 等で、コンパイル・フラグとリンク・フラグを分けて指定している場合、リンク・フラグにも-Mprof をつけてリンクを実行してください。

Question  11. リンカーに未定義の関数参照を無視してリンクするように指示するオプション/フラグはありませんか (Linux)

Answer

 pgcc -o a.out test.c -Wl,-noinhibit-exec

リンカー ld に対して、指示するオプションの指定方法は、 -Wl,-{switch} です。無視するように指示するフラグ・スイッチは、上記に示した -noinhibit-exec です。

Question  12. リンケージ・マップを出力する方法を教えてください

Answer

コンパイル・オプションに、-m をつけてコンパイル・リンクを行ってください。リンク・フェーズが終了した後に、標準出力にリンクマップが出力されます(Linux)

  pgcc -m test.c あるいは、 pgcc -Wl,'--print-map' test.c

さらに、リンケージのクロスリファレンスを出力する場合は、以下のように行います。

  pgcc -m -Wl,'-cref' test.c あるいは、 pgcc -Wl,'--print-map','-cref' test.c

Question  13. LAPACK を使用する際のリンク・オプションを教えてください

Answer

PGI 5.0 以前のバージョンでは、標準の最適化された LAPACK、BLAS がバンドルされています。PGI 5.1 以降のリリースでは、この標準の LAPACK パッケージの他に、AMD 社が提供するアセンブラ SSE/SSE2 インストラクションを使用して性能最適化された BLAS ライブラリ、LAPACK ライブラリ、FFT ライブラリ (AMCL) もバンドルされております。以下に、これらのライブラリをリンクする方法を述べます。

【PGI 標準 LAPACK のリンク】
pgf90 -fastsse test.f -llapack -lblas -lpgftnrtl

【AMD ACMLライブラリの使用】
pgf90 -fastsse -Mcache_align test.f -lacml   (-Mcache_align は必ず指定してください)

詳細の説明は、こちらのページへ

Question  14. Sun, SGI 等の UNIX システムで実行した結果と PGI での計算結果が微妙に異なるのですが、どのような原因が考えられますか

Answer

x87 の内部レジスタは、80-bit を有し、PGI コンパイラのデフォルトは、x87 の 80-bit 精度での内部演算を行います。一方、レガシーなRISC/UNIX システムでは、64-bit レジスタによる 内部演算処理を行っているため、これによる計算精度の差が出てくるのが一般です。PGIコンパイラは、x86 の内部演算精度を 80-bit, 64-bit, 32-bit に制御することが可能ですので、以下のオプションをセットして、実行結果を比較してください。これに関する詳細な技術情報は、こちらのページをご覧ください。
なお、以下の説明は、当該プロセッサが過去の Pentium III 以前のプロセッサに関しての事項です。これ以降のプロセッサでは x87 系の演算系を使用していないか、そもそも有していません。

-pc 80 (default)
-pc 64 (64-bit精度)
-pc 32 (32-bit精度) これらは、過去のx86プロセッサ(Pentium 3/4)に対してのみ有効です

-Kieee (浮動小数点演算の処理方式を厳密に IEEE 754 に準拠した計算方式を有効化)

Question  15. Fortran プログラムの終了時に出力される FORTRAN STOP を抑制することができますか

Answer

環境変数 NO_STOP_MESSAGE を指定して実行してください。値は任意です。

Question  16. Fortranプログラムが何らかの理由(例えばエラーや人為的に終了させるなど)で途中でストップしたとき、その時点までの結果がファイルに書き出されるようにするにはどうすればよいのでしょうか

Answer

以下のようなプログラムを実行すると、プログラムは==>マークでストップします。このとき、test1.outには1~10の数字が記入されていますが、test2.outには何も記入されていません。これを、test2.outにもエラーを起こす直前までの結果を書き出させるようにする方法はないのでしょうか?

     integer i,j
     open(1,file='test1.out',status='unknown')
     open(2,file='test2.out',status='unknown')
     j=0
     do i=1,10
       write(1,*) i
     enddo
     close(1)

     do i=1,10
       write(2,*) i
  ==> if(i==5) j=1/j
     enddo
     close(2)
     end

【回答】
これは、ファイルI/O の書き出すタイミングについての問題かと思います。言語処理系における、ファイルI/O のタイミングに関しては、規約はなく、それぞれの実装系に依存します。PGIのファイルI/O の場合は、I/O性能を向上させるために、一旦、ライブラリ・バッファに入れてから、あるタイミングで、物理的なI/O(ファイルへの実際の書き出し)を行うようになっております。

Fortran 文の I/O -------> Buffer(Memory) ---------> file への入出力
(Logical I/Oと称する)  (call flush)       (Physical I/Oと称する)

従って、何らかの interrupt がプログラムに生じたばあい、buffering されている内容が書き込まれないという現象が生じます。まさにこれが、二つ目のループの test2.out の書き込みの際に起きているわけです。

バッファ内容をを強制的に書き出すためには、そのためのコマンドをプログラムに入れる必要があります。いわゆる Fortranレベルで使用可能なシステム関数(3F functions) を使用します。

  CALL FLUSH(unit番号)

     do i=1,10
      write(2,*) i
 ==> if(i==5) j=1/j
       CALL FLUSH(2)
     enddo

上記の文は、unit番号にかかわる buffer の内容を書き出す指示を出すためのものです。一般には、何かのトラブル時にdebug のために入れることが多い構文となります。特に、下記のように ループ内に入れた場合はパフォーマンスに影響します。
このような状況を理解していただき、何かあったときに Flush を行うとか、あるいは、一つのプログラムフローの中であるマイルストーンを過ぎた時点で、とりあえず、call flush 文を入れてファイルに書き出しておくというような使い方になります。

他のコンパイラでは、logical I/Oがあった時点で Physical I/O も行うという仕様もありますが、これは、スループット性能を落とす要因となります。PhysicalI/O はレコードサイズが小さければ小さいほど、オーバーヘッドの高い時間の掛かる処理です。PGIと他のコンパイラとは、言語処理系の違いですので、ご理解ください。

何か問題があったときの I/O のトレースを行う場合は、デフォルトで落ちた時点でのファイル内容が見られれば良いと思いますが、何も問題がないときは、性能のほうが重要となりますので、PGIの形式の方が良いです。
状況によって、どちらの形式が良いとは言えませんので、PGIの場合は FLUSH文を入れていただければと思います。なお、FLUSH 文は汎用的に使用できる構文ですので portability 的にも問題ないと思います。


(関連質問)
2007年 10 月 17 日追加
-------------------------------------------------------------------------------
PGI Fortranコンパイラでは、OPEN文などにて開いたファイルにwrite文などにより書き込んだ場合、バッファリングされていると思います。
そのため、プログラムを途中でkillした場合、バッファリングされていたデータがファイルへ反映されませんので(プログラム終了まで実際に書き込まれない場合が多い)、このバッファサイズをPGIコンパイラ側で調整することは可能でしょうか?それとも、これはOS側の設定によるものでしょうか?
また、バッファリングされていてファイルシステムに書き込まれていない場合、CLOSE 文にてファイルを閉じた場合にCLOSE文内部でバッファが確実にflushされるのでしょうか?それとも、PGI コンパイラで用意されているflush文が必須でしょうか?
-------------------------------------------------------------------------------

バッファサイズの変更は、PGI提供のライブラリ・ルーチンを利用して可能です。

一般に Fortran/C/C++ 言語を使用する、User I/O のハンドリングは、コンパイラが提供する I/O ライブラリ-> GNU glibc のロジックを経由して、OS が提供する System Cache の機構を使用して処理します。従って、ユーザプログラムから見た場合、I/O データをハンドリングするのは、PGI 提供の I/O 関係のライブラリが、所望するハンドリングが可能かどうかで決まります。特に、バッファサイズの変更は、Low level では、OS の設定で System Cache 等の設定は可能ですが、これは Linux file system 等の全体の tuning parameter であり、ユーザ個々のプロセスの I/O handling を支配するものではありません。従って、こうしたチューニングは、OS 側ではなく、その上位の glibc ライブラリとコンパイラの提供する I/O ライブラリ側で処理することが必要です。

そこで、本論ですが、PGI の Fortran では、以下のライブラリを提供しています。

  http://www.softek.co.jp/SPG/Pgi/doc/pgifortref.pdf
  3F ライブラリにある setvbuf3f ルーチンを参照してください。

integer function setvbuf3f(lu, type, size)

Argument       Description
-------------------------------------------
integer lu       The logical unit
integer type     0 - Full buffering
           1 - Line buffering
           2 - No buffering
integer size     The size of the new buffer

このルーチンを I/O の前にセットして、I/O特性を定義します。なお、このルーチンは Linux System Call である setbuf 関数へ繋ぐための Fortran routine です。詳細は man setbuf(3) も参考にしてください。特に、 Full buffering、Line buffering、No buffering の設定により、今回のような問題に対処することになります。

-------------------------------------------------------------------------------------------
また、バッファリングされていてファイルシステムに書き込まれていない場合、CLOSE文にてファイルを閉じた場合に CLOSE文内部でバッファが確実にflushされるのでしょうか?それとも、PGIコンパイラで用意されている flush文が必須でしょうか?
-------------------------------------------------------------------------------------------
Close文での処理は、一般に、バッファの内容をフラッシュする処理も含むはずです。ただ、不安であれば、必ず、 FLUSH を行ってから close してください。

Question  17. Intel Fortran、Compaq Fortran のような「環境変数」により、ユニット機番とファイル名を連結する方法について

Answer

PGIコンパイラにおいては、Intel Fortran、Compaq Fortran のような「環境変数」により、ユニット機番とファイル名を連結する機能はありません。
  (例)setenv FORT10 test.plt ( あるいは export FORT10=test.plt)

その代わり、以下のような方法で、プログラム起動シェル上から同様な機能を実現できます。
PGI の場合、 OPEN 文においてファイル名を定義していない場合、あるいは、明示的に OPEN 文を指定しない場合は、デフォルトのファイル名は、以下のような形式となります。

  fort.xxx : xxx がユニット機番名

例えば、

  write(110) aaa

の場合は、fort.110 が自動的に作成されます。そこで、この機番ファイル名を予めシェルスクリプト上で、シンボリックリンクで「真のファイル名」にリンクしておくことにより、同様なことが実現できます。

  --- shell script ----
  ln -s test.plt fort.10
   ...プログラム実行のためのスクリプト本体...
  rm fort.10 (実行後、必要がなければ delete する)
  ---- script 終了 ----

ln コマンドは、シンボリックリンクの方が良いと思われます。(ハードリンクの場合は、定義するそれぞれのファイルが存在していなければなりませんので)

Question  18. Fedora Core 4 等においてデフォルトで SELinux (セキュアLinux) が動作しているシステムで、PGI ユーティリティの pgdbg、pgprof が起動時に Java のエラーで落ちます

Answer

PGI のデバッガ並びにプロファイラ (pgdbg, pgprof ) は、Java Runtime Environment を使用して実行されます。その際、以下のような Java のエラーメッセージでユーティリティの起動画面が立ち上がらない問題が発生することがあります。以下の例の場合は、ソケットを開こうとしてエラーになっているネットワーク接続関連のエラーです。

PGDBG 6.0-5 x86-64 (Workstation, 4 CPU)
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.

jisx0208.1983-0" to type FontStruct
java.lang.reflect.InvocationTargetException
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.
invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.
invoke(DelegatingMethodAcces.sorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:324)
  at splashLoader$1.run(Unknown Source)
  at java.lang.Thread.run(Thread.java:534)
  Caused by: java.net.SocketException: Invalid argument or cannot assign
  requested

  address
  at java.net.PlainSocketImpl.socketConnect(Native Method)
  at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
  at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
  at java.net.Socket.connect(Socket.java:452)
  at java.net.Socket.connect(Socket.java:402)
  at java.net.Socket.<init>(Socket.java:309)
  at java.net.Socket.<init>(Socket.java:124)

上記のような場合は、SELinux の機能を disable にして再起動後、再度ご確認ください。Fedra Core 4 では SELinux が標準で入っていて、有効になっていると色々と問題が起きるようです。 SELinux の確認方法や無効にする方法については、以下を参考にしてください。 なお、SELinux は、/etc/sysconfig/SELinux の SELinux=enforcing の行を SELinux=disabled にして再起動すると無効に出来ます。

 http://tempest.dcnblog.jp/blog/2005/06/fedora_core_4.html
 http://tempest.dcnblog.jp/blog/2005/06/fedora_core_4se_b93a.html
 http://faq.justsystem.co.jp/faq/1003/app/jsfaq.jsp?33417+0250
 http://www.geocities.jp/code_air_edge/HP/fc4.html

Question  19. RedHat Enterprise 4 上で、PGI ユーティリティの pgdbg、pgprof を起動する際にlibXp.so.6 がオープンできないと言うエラーで落ちます

Answer

PGI のデバッガ並びにプロファイラ (pgdbg, pgprof ) は、Java Runtime Environment (JRE) を使用して実行されます。以下のような libXp.so.6 に関する問題が発生した場合は、 JRE-1.5.x をシステムにインストールしてください。

PGDBG 6.0-4 x86-64 (Workstation, 4 CPU)
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/pgi/linux86-64/6.0/jre/lib/i386/libawt.so: libXp.so.6: cannot open shared object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1503)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:50)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.Toolkit.loadLibraries(Toolkit.java:1437)
at java.awt.Toolkit.<clinit>(Toolkit.java:1458)
at splashLoader.main(Unknown Source)
-------------

JRE-1.5.x は、以下の URL から Linux 用のソフトウェアをダウンロードしてください。なお、ソフトウェアのインストール方法は、このページに明記されております。

 http://www.java.com/ja/download/manual.jsp

新しく、JRE-1.5.x をインストールした directory をここでは仮に、/opt/java/jre_15 とした場合、PGI_JAVA 環境変数を以下のようにお使いのシェル上で定義します。これによって、pgdbg/pgprof ユーティリティは、この新しい JRE 環境を使用して起動されます。

 (csh/tcsh)
  setenv PGI_JAVA /opt/java/jre_15/bin/java
 (sh/bash)
  export PGI_JAVA=/opt/java/jre_15/bin/java

したがって従って、この環境の下で、再度、PGI ユーリティを起動してください。

デバッガ、プロファイラ等の FAQ は、新しいページを設けました。こちらのページもご参照下さい。)

Question  20. 開発中のプログラムが突然、segmentation fault で終了します。どこの部分で終了したか調べる方法はありますか

Answer

プログラムの実行時に、Segmentation fault と言うメッセージで異常終了することがあります。もし、プログラムの開発中に起きた現象であれば、プログラムのバグによる問題と思われますが、このメッセージだけでは場所を特定できません。このような場合の対処法を述べます。まず、その前に、Segmentation fault が生じる可能性のある原因について、いくつか列挙します。

(1) 配列のインデックスの定義を何らか理由で行っていない場合、この配列に参照する際、添字の範囲外のアクセスが生じて、カーネルが Segmentation fault によってインターラプトする場合(配列境界外のアクセス)
(2) OpenMP 等のスレッド並列実行する際に、システムのデフォルトの STACKSIZE では足りない領域が要求された場合
 == > これに関しては、こちらをご参考にしてください
(3) コンパイラ自身の問題によるインターラプト

大きな理由として上記の三つがありますが、ここでは、ユーザプログラムの問題としてよく生じる、(1) についての対処法を説明します。 配列境界は、コンパイラの世界では「バウンズ(bounds)」と言い、そのチェックを行うことをバウンズ・チェックと言います。PGI コンパイラでは、この機能をランタイムで行うためのオプションが存在します。コンパイル時に、以下の -Mbounds オプションを入れてモジュールを作成してください。これを実行しますと、問題が存在するところでメッセージと共にプログラムは終了します。

(コンパイル)
$ pgfortran -Minfo -fastsse -Mbounds test.f
あるいは、
$ pgfortran -Minfo -fastsse -C test.f

配列境界外のアクセスを行った場合、以下のような形式で出力されます。問題となるソースコードのライン番号とその当該配列名、実際に実行時に使用された添字の数(subscript) 、そして、配列の何次元目に問題があったか等のメッセージが出力されます。これは、明らかなプログラムバグですので、修正してください。これで、本問題は、ほとんどのケース解決されます。

【Fortran の場合】
$ ./a.out
PGFTN-F-Subscript out of range for array a (add.f: 211)
subscript=99919, lower bound=1, upper bound=2, dimension=2

【C の場合】
PGC-F-Subscript out of range for array ST2 (test.c: 385)
subscript=2, upper bound=1, dimension=1

----------------------------------------------------------------------------------------
それでは、次に、このバウンズの問題以外で segmentation fault が生じた場合、どのような方法でその場所を特定するか説明します。最も簡単に行う方法は、PGI デバッガ pgdbg を使用することです。 pgdbg は、 X環境での GUI ベースのソース・デバッガですが、場所を特定することだけであれば、テキストベースによるコマンド・インタフェースでデバッガを実行します。以下の方法で行ってください。
デバッガで実行しますと、以下のように、問題となる箇所(ソース名とライン番号)を示して終了します。

【デバッガを使用する際のコンパイルのオプション】
$ pgfortran -g -O0 test.f

【デバッガを使用して実行する】
$ pgdbg -text ./a.out
PGDBG 6.0-8 x86-64 (Workstation, 4 CPU)
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.
***Reading DWARFv2 Information.
Loaded: /home/taro/PGI/SEGFAULT/a.out

pgdbg>run < data   (注) "< data" は data ファイルを標準入力からデータを渡すと言う意味です。
                  入力データがなければ、run だけでよい。
reloading:
/home/taro/PGI/SEGFAULT/a.out
libc.so.6 loaded by ld-linux-x86-64.so.2.
libm.so.6 loaded by ld-linux-x86-64.so.2.

Signalled SIGSEGV at 0x419ECA, function mat_add, file test.F, line 3807  <== ここが終了したポイントです
419ECA: 66 F 13 84 C1 C8 EF F4 FF movlpd %xmm0,-725048(%rcx,%rax,8)

PGDBG の GUI バージョンを使用するとSegmentation fault の場所で終了し、ソースレベルで場所の特定が可能。
PFGDEBUG

Question  21. 新リリース PGI 6.1 を /usr/pgi 配下にインストールしました。過去のバージョンの PGI 5.2、6.0 ソフトウェアも、/usr/pgi 配下に削除せず残しています。デフォルト・バージョンは PGI 6.1 の状態で、過去のバージョンを使用する方法はありますか

Answer

PGI コンパイラのソフトウェアは、デフォルトでインストールした場合、/usr/pgi ディレクトリ配下に実装されます。ソフトウェアのバージョン管理方法は、/usr/pgi 配下に以下のようなバージョン番号のサブ・ディレクトリが作成され管理されています。バージョンアップを繰り返し、過去のバージョン・ソフトウェアをシステム上に残留させた場合、例えば、5.2、6.0、6.1 と言うディレクトリが作成されています。

【32-bit コンパイラ用】       【64-bit コンパイラ用】
/usr/pgi/linux86/5.2        /usr/pgi/linux86-64/5.2  : PGI 5.2ソフトウェア
/usr/pgi/linux86/6.0        /usr/pgi/linux86-64/6.0  : PGI 6.0ソフトウェア
/usr/pgi/linux86/6.1        /usr/pgi/linux86-64/6.1  : PGI 6.1ソフトウェア(現在のデフォル)

上記のような状態で、ソフトウェアが実装されていた場合、コンパイラ・オプションの指定により、過去のコンパイラ・ソフトウェアを使用することができます。 -V{Release_number} オプションをコンパイラ・コマンドに付けることで、過去のバージョン番号のコンパイラを使用してコンパイルが可能となります。

(例) pgcc -V5.2 myprog.c 

(関連情報)最新バージョンだけでなく、過去のバージョンも同時にインストールして各々動作しますか (Linuxの場合)

Question  22. PGI 6.1 の PGDBG/PGPROF を使用する際、Java Runtime Environment が1.5.0_04 以上を必要とされると言うメッセージが出ます

Answer

PGI のデバッガ並びにプロファイラ (pgdbg, pgprof ) は、Java Runtime Environment (JRE) を使用して実行されます。最新の Linux distribution を使用していない場合、JRE が古い場合があります。以下のようなメッセージが出力された場合は、 JRE-1.5.04 以上にバージョンアップしてください。

$ pgdbg

pgdbg: The PGDBG Graphical User Interface (GUI) requires java JRE 1.5.0_04
pgdbg: or higher. Using Text Interface.

PGDBG 6.1-1 x86-64 (Workstation, 4 CPU)
Copyright 1989-2000, The Portland Group, Inc. All Rights Reserved.
Copyright 2000-2005, STMicroelectronics, Inc. All Rights Reserved.
-------------

JRE-1.5.x は、以下の URL から Linux 用のソフトウェアをダウンロードしてください。なお、ソフトウェアのインストール方法は、このページに明記されております。 AMD64/EM64T の64bit のシステムでは、AMD64 用のバイナリをダウンロードしてください。なお、インストールは rpm コマンドで行われますので、JRE の環境はシステム内部に自動的に設定されます。従って、 PGI_JAVA 環境変数の設定は必要ありません。

 http://www.java.com/ja/download/manual.jsp

インストール後、この環境の下で、再度、PGI ユーリティを起動してください。

デバッガ、プロファイラ等の FAQ は、新しいページを設けました。こちらのページもご参照下さい。)

Question  23. SUSE 10.0 (64bit) 上で PGI 6.0-8 を使用しています。コンパイルオプションに -Mipa を使用すると、リンク時にエラーが生じます。この対処法を教えてください

Answer

PGI 6.0 は、SUSE 10.0 を正式にサポートしていませんが、この OS の上で、PGI 6.0 を使用する場合も多いかと思います。SUSE 10.0 上で、コンパイルオプションに -Mipa を使用して実行モジュールを生成する際に、リンク時に以下のようなメッセージで正常終了しません。なお、PGI 6.1 ではこのような問題は生じません。
 
   File format not recognized

この問題は、 SUSE 10.0 にバンドルされているパッケージの binutils の 2.16.91.0.2 バージョンに伴う問題です。以下に、これに対処するための方法を説明します。

① 弊社のサイトから、 suse10_patch.tar.gz (パッチファイル)をダウンロードしてください。
② ルート権限でログインし、 PGI をインストールしたトップ・ディレクトリ(/usr/pgi )に上記のパッチファイル移動してください。
③ 以下の操作を行ってください。

【パッチファイルの展開】
$ cd /usr/pgi
$ ls suse10_patch.tar.gz
suse10_patch.tar.gz
$ tar xzvf suse10_patch.tar.gz (パッチ内容を linux86-64/6.0 配下に展開します)

【パッチでインストールされた共有ライブラリのパスをシステムに登録】
$ cd /etc
$ vi ld.so.conf (ld.so.conf ファイルを開き、以下の「パス」を登録)
/usr/pgi/linux86-64/6.0/patch   <==== これを ld.so.conf ファイルの中に追加してください

$ ldconfig (追加したパスをシステムに反映する)
これで終了です

Question  24. PGI 6.1 をインストールし、コンパイル後実行した際に、 GLIBC_2.2.5 not defined と言うエラーが生じます。この対処法を教えてください

Answer

PGI 6.1 を使用して、OpenMP 並列あるいは、自動並列化した実行モジュール (-mp or -Mconcur オプション付き) を実行すると、以下のようなメッセージでエラーが生じる場合があります。これらの実行モジュールは、システムの libpthread ライブラリを使用するものです。また、この問題が生じる Linux のバージョンは特定されていませんが、 RedHat Enterprise 3 の古いアップデート・バージョン等の Linux kerner 2.4.x のもので起こりうることが報告されております。米国 PGI 社でもこれは、既知の問題として認識されておりますが、 Linux distribution に係る問題のため、OSのアップデート等を行う他は、根本的な解決はできません。しかし、以下に述べる方法で、対処が可能です。

  relocation error: /usr/pgi/linux86-64/6.1/lib/libpthread.so.0:
  symbol _h_errno, version GLIBC_2.2.5 not defined in file libc.so.6 with link time reference

ユーザ、あるいはシステムレベルで、 .bashrc or .cshrc 等のファイルで以下のような LD_ASSUME_KERNEL 環境変数の設定を行うことでこの問題への対処が可能です。

例えば、お使いの Linux のカーネルバージョンが 2.4.x であれば、以下のようにご指定ください。 
  export LD_ASSUME_KERNEL=2.4.1

また、お使いの Linux のカーネルバージョンが 2.2.x であれば、以下のようにご指定ください。
  export LD_ASSUME_KERNEL=2.2.5

なお、Linux のカーネルバージョンの調べ方は、 cat /proc/version のコマンドで表示されます。

この問題と同じようなものが、PGI User Forum 上に記録されております。
 http://www.pgroup.com/userforum/viewtopic.php?t=539 
 http://www.pgroup.com/userforum/viewtopic.php?t=207

別の解決法としては、各ユーザのログイン環境変数の設定(.bashrc あるいは、.cshrc) において、以下の環境変数を設定することで回避できるようです。(以下は 64bit 環境の場合)
 export LD_LIBRARY_PATH=/lib64/tls:/opt/pgi/linux86-64/6.1/lib
 

 

Question  25. PGI コンパイラで生成したオブジェクト・ファイルの PGI バージョンに依存した互換性について教えてください

Answer

(2007年4月26日)
Linux版、Windows版 に係らず、PGIコンパイラが生成するオブジェクト・ファイルの互換性 (旧バージョンで作成したオブジェクトあるいは、ライブラリをリンクして動作可能かと言うこと) について説明します。

 PGI 5.x
 ----------- オブジェクト互換性の境界
 PGI 6.0
 PGI 6.1
 PGI 6.2
 PGI 7.0

オブジェクトの互換性は、PGI 5.x 以前と PGI 6.x 以降では、基本的に互換性はないものと考えて下さい。これは、Linux/Windows版共通です。これがまず、基本原則です。バージョン間での互換性がないオブジェクトを使用する際は、ソースファイルからの再コンパイルをお願いいたします。
さらに、PGI 6.1以前のバージョンでコンパイルオプション -Mipa(手続き間最適化)を付加して生成したオブジェクトは、PGI 6.2以降のオブジェクトとの完全互換はありませんので、再コンパイルが必要です。

次に、Windows バージョンは、使用するシステム・ライブラリが PGI 6.1 以降変更になっております。(弊社では、PGI6.1 以降の Windows版を正式に販売しており、それ以前のバージョンは、日本では販売しておりません)

 PGI 5.x  Cygwin上での32bit版のみ Linux-like environment (MINGW)
 PGI 6.0  Cygwin上での32bit版のみ Linux-like environment (MINGW)
 --------- Cygwin / Microsoft のシステムライブラリ使用の境界-------------
      以降、ネイティブ Microsoft SDK(utility) を使用したコンパイル環境に変更
 PGI 6.1  64bit版のみリリース/32bit版は欠番
 PGI 6.2  64bit版、32ビット版ともにリリース
 PGI 7.0  同上

Question  26. Linux のアップデートにより GCC/Glibc のバージョンが変更された後、リンク時に GNU 関連のライブラリがリンクできず、実行モジュールの生成ができません

Answer

(2012年2月25日更新、2007年7月12日初稿)
この問題は、システムの GNU/GCC ライブラリのバージョンが、オンラインアップデートで更新されたために生じる問題です。

Red Hat Enterprise Linux のような商用ディストリビューションでは、オンライン・アップデートする機会が多いため、かなり頻繁に GNU パッケージのバージョンがアップデートされます。PGI コンパイラは、GNU/GCC のライブラリやインクルードファイルを使用しており、PGI コンパイラをインストールした時点で、システムに実装された GNU/GCC ライブラリ等のバージョン(厳密に言えば、存在するディレクトリ・パス)を PGI コンパイラの初期設定ファイル (一例:$PGI/linux86-64/{vesion}/bin/localrc) に登録しています。
  (各 Linux distributions バージョンの GCC/glibc のバージョンに関してはこちらで

もし、GNU/GCC のバージョン(たとえば、初期 GCC 3.4.4)が、オンライン・アップデートで GCC 3.4.5--> GCC 3.4.6 に順番に上がりますと、すでに登録してある PGI 初期設定ファイルの中の GCC 関係のパス名(Linux ではバージョン番号がパス名として使用している)とシステムの実態が異なる形になります。一般には、システム上でこのような GCC 等のアップデートを行うと、旧バージョン名(たとえば 3.4.5)は、実態のあるバージョンを引用できるように、シンボリック・リンクを張るのですが、Red Hat Enterprise Linux 4 等では、このリンクは最新のバージョンのものしか、シンボリックに結合していないため、頻繁にアップデートされますと、PGI 初期設定ファイルの中のGCCパス名が存在しない事態になることがあります。このような状況でコンパイルを行うと、従来可能であったことが突然コンパイルエラーとなる状況があり得ます。
 
% pgcc -c test.c
PGC-F-0206-Can't find include file stddef.h (/usr/include/stdio.h: 34)
PGC/x86-64 Linux/x86-64 6.1-1: compilation aborted
あるいは、
% pgf90 t.f
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/4.4.5/crtbegin.o: No such file: No such file or directory

PGI の初期設定ファイルの内容とシステムのアップデート状況を確認してください。

【PGI の初期設定ファイル(localrc) の場所】
 PGI 32ビット環境の場所 : $PGI/linux86/{version 番号}/bin/localrc
 PGI 64ビット環境の場所 : $PGI/linux86-64/{version 番号}/bin/localrc

その内容の一例(以下の例では、 GCC 3.4.4 が初期設定されています)
 % cat $PGI/linux86-64/{version 番号}/bin/localrc
 set LFC=-lg2c;
 set LDSO=/lib64/ld-linux-x86-64.so.2;
 set GCCDIR=/usr/lib/gcc/x86_64-redhat-linux/3.4.4/;
 set GCCINC=/usr/lib/gcc/x86_64-redhat-linux/3.4.4/include;
 set G77DIR=/usr/lib/gcc/x86_64-redhat-linux/3.4.4/;
 (以下、省略)

上記の GCCDIR のディレクトリを確認してください。(3.4.4ディレクトリ、あるいはリンクはすでに消去されています)
 % ls /usr/lib/gcc/x86_64-redhat-linux/
 3.4.3/ 3.4.6@ 4.1.1/

こう言った形で、オンラインアップデートを行うと、旧GCCのバージョンのリンクが切れることになります。
なお、現在実装されている gcc のバージョンを調べるには、以下のコマンドを使用します。
 % gcc --version
 gcc (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)
それでは、これに対する解決策を説明します。PGI の初期設定ファイル localrc を現在のシステム環境(GCCバージョン等)に沿うように更新します。もちろん、PGIを再インストールしても解決しますが、ここでは、再インストールを行わず、最も簡単な解決策を以下に示します。

ルート権限で以下の処理を行います。
セッションのシェルの言語モードを一時的に英語モードにする(必須)。

# export LANG=C

次に、PGIのインストール場所を $PGI として、以下の処理を行います。
PGI {version 番号} の初期設定ファイル (localrc) をアップデートします。{version 番号}は、6.0 とか 6.1、7.2-1 と言うバージョン番号です。

64ビット用コンパイル環境を行います。
# cd $PGI/linux86-64/{version 番号}/bin
# ./makelocalrc -x $PGI/linux86-64/{version 番号}
(例:./makelocalrc -x $PGI/linux86-64/7.*) PGI 7.0 以前のバージョン表記例
(例:./makelocalrc -x $PGI/linux86-64/7.2-*)PGI 7.1 以降のバージョン表記例
(例:./makelocalrc -x $PGI/linux86-64/10.*) PGI 10.0 以降のバージョン表記例

同様に、32ビット用コンパイル環境も行います。
# cd $PGI/linux86/{version 番号}/bin
# ./makelocalrc -x $PGI/linux86/{version 番号}

以上で、現在の gcc /glibc バージョンが反映された PGI の各バージョンの初期設定ファイルの変更が可能です。これで、問題なく、コンパイルできるはずです。なお、過去のバージョン、リビジョンを複数実装している場合は、その全てを同じように makelocalrc で処理する必要があります。この場合は、以下のようなシェルスクリプトを使い、各バージョンの localrc ファイルを変更できます。

(一例を示します)
[root@photon29 linux86-64]# pwd
/opt/pgi/linux86-64            (64bit環境)
[root@photon29 linux86-64]# ls (以下のようなバージョンが実装されています)
10.0  10.2  10.4  10.6  10.9  11.1   11.2  11.4  11.6  11.8  12.1  2010  2012  9.0-4
10.1  10.3  10.5  10.8  11.0  11.10  11.3  11.5  11.7  11.9  12.2  2011  9.0 
change-makelocalrc-64
[root@photon29 linux86-64]# cat change-makelocalrc-64 (変更するためのスクリプト例)
#! /bin/bash

for ver in 9.0-4 10.0 10.2 10.4 10.6 10.9 11.1 11.2 11.4 11.6 11.8 12.1 10.1 10.3 10.5 10.8 \
 11.0 11.10 11.3 11.5 11.7 11.9 12.2
  do
        echo $ver " set"
        cd $ver/bin
        ./makelocalrc -x $PGI/linux86-64/$ver
        cd ../..
  done
[root@photon29 linux86-64]# ./change-makelocalrc-64   (スクリプトの実行)
 ... 過去のバージョンでは、以下に述べるエラーメッセージが出る場合があるが、これは無視する...
以上で 64ビット環境の localrc ファイルは全て変更されるはずです。

次に 32bit環境も行う。
[root@photon29 linux86-64]# cd ../linux86
[root@photon29 linux86]# pwd   (32bit環境)
/usr/pgi/linux86
[root@photon29 linux86]# ls
10.0  10.2  10.4  10.6  10.9  11.1   11.2  11.4  11.6  11.8  12.1  2010  2012  9.0-4
10.1  10.3  10.5  10.8  11.0  11.10  11.3  11.5  11.7  11.9  12.2  2011  9.0 
change-makelocalrc-32
[root@photon29 linux86]# cat change-makelocalrc-32
#! /bin/bash

for ver in 9.0-4 10.0 10.2 10.4 10.6 10.9 11.1 11.2 11.4 11.6 11.8 12.1 10.1 10.3 10.5 10.8 \
 11.0 11.10 11.3 11.5 11.7 11.9 12.2

  do
        echo $ver " set"
        cd $ver/bin
        ./makelocalrc -x $PGI/linux86/$ver
        cd ../..
  done 
[root@photon29 linux86-64]# ./change-makelocalrc-32   (スクリプトの実行)

【過去のバージョンの既知の問題】
(バージョン番号が、 7.0以前の場合の指定例)
$ ./makelocalrc -x $PGI/linux86-64/7.0
cp: cannot stat `/usr/pgi-7.0/linux86-64/7.0/lib/libpgbind_real.a': No such file or directory
cp: cannot stat `/usr/pgi-7.0/linux86-64/7.0/libso/libpgbind_real.a': No such file or directory
cp: cannot stat `/usr/pgi-7.0/linux86-64/7.0/libso/libpgbind_real.so': No such file or directory
localrc has not changed
(バージョン番号が、 7.1以降の場合の指定例、パッチリビジョン 7.2-* まで指定する)
$ ./makelocalrc -x /opt/pgi/linux86-64/7.2-2
cp: cannot stat `/opt/pgi/linux86-64/7.2-2/lib/libpgbind_real.a': No such file or directory
cp: cannot stat `/opt/pgi/linux86-64/7.2-2/libso/libpgbind_real.a': No such file or directory
cp: cannot stat `/opt/pgi/linux86-64/7.2-2/libso/libpgbind_real.so': No such file or directory
localrc has not changed

過去のバージョンでは既知の問題があり、上記のエラーメッセージは「無視」して結構です。また、”localrc has not changed”と言うメッセージも「無視」してください。実際には、再設定されて変更されています。(再度、localrcの内容を確認してみてください) 念のため、 ls -lt で、 localrc と locarc.bak ファイルの二つの内容 と更新日付を確認して見てください。適格なGCCバージョンがセットされていれば、問題なく動作します。

Question  27. PGI 7.1 からバンドルされた MPICHライブラリや、MPIプログラム用のツールの使用方法を教えてください

Answer

PGI Workstation/Server ライセンス製品と PGI CDKライセンス製品で使用可能な MPICH ライブラリの利用方法に関しては、別のページを設けましたので、こちらをご覧ください

Question  28. PGI Workstation ライセンスで生成した実行モジュールの使用可能な並列スレッド数の上限値は、バージョンによって変更されていますか

Answer

PGI Workstation ライセンスで生成した実行モジュールの「使用可能な並列スレッド数の上限値」は、各バージョンにより異なります。
過去のバージョンを使用している場合は、その上限値で制約されます。一般的には、「使用可能な並列スレッド数の上限値」は、環境変数 OMP_NUM_THREADS あるいはNCPUS で定義する数字となります。

  PGI 6.1 以前 : 4 まで
  PGI 6.2/7.0  : 8CPUソケットまでのコア総数が上限(インテル・プロセッサシステムの場合は、
          異なる場合があります)
  PGI 7.1 以降 : 最大 256 (正確には、デフォルトで内部的な最大値は 64 スレッドまでという制約が
          あります)
  もし、64 threads 以上の並列実行をしたい場合は、内部的なデフォルト値64を変更するための環境変数として、NCPUS_MAX がありますので、この値を任意に設定します。その後に、実際に実行時に使用するスレッド数を OMP_NUM_THREADS で指定して下さい。
  (一例)
  $ export NCPUS_MAX=256
  $ export OMP_NUM_THREADS=256
  $ ./a.out

PGI 7.1以降は、この制約自体を撤廃しましたので、論理的には、現在販売されているマシンの物理的な上限コア数で並列実行できます。これに関しては、以下に説明しています。
   http://www.softek.co.jp/SPG/Pgi/product_matrix70.html
   http://www.softek.co.jp/SPG/Pgi/product.html#licenses

従って、使用するコンパイラのバージョンによって、生成された実行モジュールの使用可能な並列スレッド数の上限値は変化するということを予めご了承ください。

Question  29. PGI C++コンパイラ(pgCC or pgcpp)環境において、C言語の ISO/IEC C99 規約で定義されている関数を組み込む方法を教えて下さい

Answer

例えば、nan() 等の C 言語の ISO/IEC C99 規格に準拠した関数を PGI C++コンパイラで使用する場合は、以下に述べる方法で、明示的に、関数の組込を指定しなければなりません。

以下のテストプログラムには、nan() 関数を使用しています。このプログラムファイルを test.cpp とします。

#include <iostream>
#include <sstream>
#include <cmath>

int main() {
std::ostringstream ost1;
double x = nan("");
ost1 << -x;
std::cout << ost1.str() << std::endl;
return 0;
}
------------------------------------------------- 
これをコンパイルすると、nan() 関数が見つからないと言うエラーとなる
$ pgCC test.cpp
"nan.cpp", line 7: error: identifier "nan" is undefined
double x = nan("");

1 error detected in the compilation of "nan.cpp".

以下のどちらかの方法で、 nan() 関数を明示的に include します。
① コンパイル・オプション pgCC -D_ISOC99_SOURCE test.cpp
② ソース上で定義(以下を追加)  extern "C" double nan (const char *);

#include <iostream>
#include <sstream>
#include <cmath>

int main() {
std::ostringstream ost1;
double x = nan("");
ost1 << -x;
std::cout << ost1.str() << std::endl;
return 0;
}
-------------------------------------------------
$ pgCC -D_ISOC99_SOURCE test.cpp
OK

Question  30. PGI 11.0 (PGI 2011)以降の PGFORTRAN コンパイラで実行モジュールを作成し実行すると、実行終了時に、ieee_inexact is signaling と言う警告メッセージが出ます。この意味とこのメッセージを抑止する方法を教えて下さい

Answer

 PGI 11.0 から正式に Fortran 2003 完全準拠となりました。この Fortran 2003 標準規約では、プログラムの浮動小数点演算実行時に、プロセッサ演算機構の中で一般的な IEEE の例外シグナルが発生した場合、そのメッセージをプログラム実行終了時に、出力するように求められています。今回の問題の「ieee_inexact シグナル」とは、プロセッサの浮動小数点演算において「不正確」、すなわち、丸められた有効な演算結果が、無限精度の結果と異なるような事象が少なくとも1度以上生じた場合のプロセッサ・ハードウェアによるシグナルです。これがプログラムにおいて受け入れられるものかどうかは、そのプログラムの実行時の特性によって異なります。これに関しては、ユーザの責任で判断することになります。一般に、こうした IEEE 例外事項が発生した場合は、「デフォルトの動作」により処理は続行しており、今までは気がついていない場合も多々あるのかもしれません。なお、これは、PGIコンパイラの生成コードが出すシグナルではなく、プロセッサ自体の例外処理シグナルを出力していることにご注意下さい。また、「致命的なエラーメッセージ」ではなく、「情報レベル」のメッセージであると言うこともご理解下さい。

 このメッセージの抑止方法は、プログラムの STOP 文を削除することです。 STOP 文が存在する時にのみ、Fortran 2003 の例外シグナルメッセージを出力します。あるいは、環境変数 NO_STOP_MESSAGE を設定することでも抑止されます。NO_STOP_MESSAGE に対する値の設定は「任意」です。例えば、 export NO_STOP_MESSAGE=y と言う設定で構いません。

Question  31. Sandybridge プロセッサを搭載した OS X 10.7 (Lion) 上で PGI 11.x (PGI 2011) を使用してコンパイルすると、no such instruction: `vzeroupper' と言うエラーメッセージが出ます

Answer

 2011年から発売されている Mac には、インテル(R) の Sandybridge プロセッサが搭載されています。2011 年時点で、この新しいプロセッサに対応した OS X 10.7 (Lion)上で、PGI 11.x を使用してコンパイルを行うと以下のようなアセンブラレベルのエラーが出ます。この原因は、OS X の開発環境 Xcode 4.2 (2011/12現在)に含まれる GNU 環境のアセンブラ(as) が、 Sandybridge プロセッサ対応となっていないためです。PGI コンパイラは、実行時、搭載プロセッサの種別を識別し、その CPU ターゲットに沿った最適化を行います。この環境では、PGI は、Sandybridge 用の新しいプロセッサ命令(AVX)を含む中間アセンブリコードを生成しているため、Xcode/GNU のアセンブラがこのコードを認識できなかったことにより、こうしたエラーが出現します。今後の OS X の Xcode のバージョンで対応できるものと思います。この問題は、PGI 12.10 まで更新(修正)されていません。
 (追記)PGI 13.2 (2013年2月リリース)以上、かつ Xcode 4.5.2 以上において、この問題を解決し、こうしたエラーは生じません。

Macbookpro$ pgf90 test.f90
	test.f90:74:no such instruction: `vzeroupper'
	test.f90:83:no such instruction: `vzeroupper'
	test.f90:90:no such instruction: `vzeroupper'
	test.f90:97:no such instruction: `vzeroupper'
	test.f90:101:no such instruction: `vzeroupper'
	test.f90:107:no such instruction: `vzeroupper'
	test.f90:234:no such instruction: `vzeroupper'

 この問題を回避するためには、コンパイル時に以下のオプション -tp を追加して下さい。プロセッサのターゲットを nahalem にして、実行バイナリを作成します。

Macbookpro$ pgfortran/pgcc/pgCC -tp nehalem-64  {ソースファイル名}

Question  32. PGI CDK 12.2 以降で、CDK ソフトウェアにバンドルされた MPICH2 の mpiexec を実行できません。エラーメッセージは、mpiexec: error while loading shared libraries: libpgmp.so: cannot open shared object file: No such file or directory と言うものです

Answer

 PGI CDK 12.2 の mpich2 関連のコマンド(バイナリ)内に含まれている Library PATH (-rpath) が 過去の 12.1 バージョン($PGI/linux86-64/12.1/libso)を探すようにハード・コーディングされているために、こうした問題が生じます。この問題の回避は、各ユーザの .bashrc 等に以下の2行の LD_LIBRARY_PATH を設定して下さい。以下のパス名の太字の 12.2 の部分は、インストールした CDK のリビジョン名です。これは適宜、実装リビジョン番号名に変更して下さい。

(linux86-64 の場合)
export LD_LIBRARY_PATH=$PGI/linux86-64/12.2/mpi2/mpich/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$PGI/linux86-64/12.2/libso:$PGI/linux86-64/12.2/lib:$LD_LIBRARY_PATH

Question  33. PGI 2016 (16.3)以降、Windows版は C++ コンパイラの提供が終了しました。旧バージョン PGI 15.10 の C++ コンパイラを使用できますか? その方法を教えて下さい。

Answer

 PGI 2016 以降の Windows 版では C++ コンパイラを使用することができません。しかし、PGI 15.10 以前のバージョンにバンドルされた C++ コンパイラは、PGI 2016(Fortran/Cライセンス)以降用に取得した license.dat 環境下でも使用することができます(同じライセンスファイル環境で古いバージョンを使用することができます)。なお、PGI 16.1 以降 PGPROF ユーティリティ機能が全く新しくなったため、PGI 15.10 以前の PGPROF バージョンを利用したい場合も PGI 15.10(終息バージョン)を Windows 上にインストールして下さい。但し、C++ コンパイラに関しては以下の注意事項があります。

  • 旧バージョンの Windows 版 C++ コンパイラは、ISO C++03 規格レベルのコンパイラであること。
  • Windows 版 C++ コンパイラの開発とサポートは終了しているため、バグフィックスは行われないこと。また、技術サポートも行いません。
  • Microsoft Visual C++ のオブジェクトとの ABI 互換性はありません。

 現在、PGI 16.x 以降をすでにインストールしてある環境であることを前提に説明します。新たに、PGI Workstation 15.10 をインストールして下さい。インストール方法は、弊社の「お客様専用サポートページ」内にあるインストールの手引きをご参照ください。なお、以下の注意点を守っていただければ、ダウンロードした exe ファイルを実行するだけで簡単に実装できます。

  • Microsoft(R)の Windows 8.1 SDK ソフトウェア必ずをインストールすること。Windows 10 SDK がすでに実装されている環境においてもインストールして下さい。(Windows のコントロールパネル「プログラムと機能」で調べてください)
  • インストール開始後、実装する場所を尋ねるウイザードが出ますが、これは、すでに実装されているPGIバージョンと全く同じ場所(C:\Program files\PGI) として実装してください(変更しないでください。既設のバージョンは上書きされません)。
  • インストール時のウィザードで、「PGI Workstation 15.10 のショートカットをデスクトップ上に作成するか?」の問いに対しては Yes としてください。この時点では、デスクトップ上の PGI アイコンは、先にインストールしたバージョン用のアイコンが存在していますが、PGI Workstation 15.10 用のPGIアイコンも別途作成されるはずです。但し、同じ画像アイコンですので区別して使用してください。
  • インストール・ウィザードの後半で、'Would you like to generate permanent or trial license keys?’と言う問いがありますが、これは No, I'll later (いいえ)として下さい。license.dat は、現在使用しているものが使用でき、FlexNet ライセンスマネージャ環境も新しいバージョン用の実装を使用します。

 PGI 15.10 のインストールが終了しますと、これ以降、PGI 15.10 用の PGI コマンドプロンプト端末を開くとその中で PGI C++ (旧 pgcpp コマンドを使用すること。pgc++ コマンドではありません)を使用することが出来ます。なお、デスクトップ上に PGI 15.10 用のアイコンを作成しなかった場合の、PGI 15.10 コマンドプロンプト端末の開き方を説明します。

  1. Windows の explore を開いて下さい。
  2. C:\Program Files\PGI\win64 フォルダを開いて下さい。この中に、「15.10フォルダ」が存在します。このフォルダを開くと「pgi.bat」起動用バッチファイルが存在します。拡張子を表示しないモードでは「pgi」というファイルがバッチファイルとなります。これをダブルクリックすると、PGI 15.10 のコマンドプロンプト端末が開きます。この端末内で、pgcpp コンパイラが使用できます。
  3. この pgi.bat ファイルのショートカットをデスクトップ上に置くことにより、使用して下さい。