PGI プログラム開発用 オプション
PGI の F77, F2003, C, C++ のコンパイラを使用してプログラムを開発する際に、有用なオプションを以下に示します。いずれもプログラムのデバッグを行うときに有効なオプションです。主に、pgfortran を使用した場合の例ですが、コンパイラのオプションの設定方法は、他の言語コンパイラでも同じです。
2012年2月15日更新 Copyright © 株式会社ソフテック
$ pgfortran -fastsse -Mbounds test.f あるいは $ pgfortran -fastsse -C test.f
【Fortran の場合】 PGFTN-F-Subscript out of range for array a (add.f: 211) subscript=3, 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
$ pgfortran -fastsse -Ktrap=fp test.f
inv : invalid operation denorm : denormalized operand divz : divide-by-zero ovf : overflow unf : underflow inexact: precision (現在、PGI ではサポートしない、多数の exception が発生する可能性あり) fp : inv,divz,ovf と等価 none :全てのトラップを抑止します(PGI 6.2以降)
$ pgfortran -fastsse -Kieee test.f
IEEE 754 Standard に準拠した演算とは、例えば、演算に伴う右辺、左辺のメモリ・ロード/ストアを IEEE に準拠した形で厳密に行い、最適化等による copy propagetion (変化しない変数、定数の演算上の置き換え)等を行わない計算方式などを言う。また、除算 a/b では、コンパイル時に a*(1/b) といった近似演算も disable される。さらに、内部組み込み関数への浮動小数点の引数の引渡しでは、丸めが行われる。
-M[no]fprelaxed=[div,order,recip,rsqrt,sqrt]
div : 緩い精度で除算処理を行う order : a*b+a*cをa*(b+c)と変換する方式も含め、演算の順序の変更を許す recip : 緩和した精度で逆数近似 (PGI 9.0 以降) rsqrt : 緩い精度でsqrtの逆数近似(1/sqrt)の処理を行う sqrt : 緩い精度でsqrtの処理を行う なお、サブオプションを付加しない場合(-Mfprelaxedのみ)は、そのターゲットプロセッサに応じて、 顕著な性能向上が行える処理に、緩い精度での処理を行うかを選択し適用される。
-M[no]fpapprox[=div|sqrt|rsqrt]
div : 浮動小数点除算近似 rsqrt : 浮動小数点平方根近似 sqrt : 浮動小数点逆数平方根近似 デフォルトでは、-Mfpapprox は使用されません。もし、サブ・オプションを指定しない -Mfpapprox のみの場合は、上記の全てのサブ・オプションが指定されたものとして扱います。
$ pgfortran -fastsse -pc 64 test.f
$ pgfortran -fastsse -Mvect=assoc test.f
$ pgfortran -fastsse -Mlre[=array|assoc|noassoc] test.f
$ pgfortran -fastsse -byteswapio test.f
(例) % more rtest.f program test real*4 ssmi OPEN(UNIT=10,FILE='ice.89',FORM='UNFORMATTED') read(10) ssmi print *,'OK: ',ssmi end % more wtest.f program test real*4 ssmi ssmi = -999 OPEN(UNIT=10,FILE='ice.89',FORM='UNFORMATTED') write(10) ssmi print *,'OK: ',ssmi end On your Sun workstation (or other big-endian device) f77 -o w_sparc wtest.f f77 -o r_sparc rtest.f On your PGI workstation. pgf77/pgfortran -o w86 wtest.f pgf77/pgfortran -o w86_swap -byteswapio wtest.f pgf77/pgfortran -o r86 rtest.f pgf77/pgfortran -o r86_swap -byteswapio rtest.f ------------------------------------------ If you write the file | Then read the file ice.89 with | ice.89 with w_sparc or w86_swap | r_sparc or r86_swap w86 | r86
$ pgfortran -fastsse -Minfo=intensity test.f
PGF90 (Version 10.1) 01/29/2010 11:33:44 page 6 ( 292) do loop=1,nn ( 293) gosa= 0.0 ( 294) do k=2,kmax-1 ( 295) do j=2,jmax-1 ( 296) do i=2,imax-1 ( 297) s0=a(I,J,K,1)*p(I+1,J,K) & ( 298) +a(I,J,K,2)*p(I,J+1,K) & ( 299) +a(I,J,K,3)*p(I,J,K+1) & ( 300) +b(I,J,K,1)*(p(I+1,J+1,K)-p(I+1,J-1,K) & ( 301) -p(I-1,J+1,K)+p(I-1,J-1,K)) & ( 302) +b(I,J,K,2)*(p(I,J+1,K+1)-p(I,J-1,K+1) & ( 303) -p(I,J+1,K-1)+p(I,J-1,K-1)) & ( 304) +b(I,J,K,3)*(p(I+1,J,K+1)-p(I-1,J,K+1) & ( 305) -p(I+1,J,K-1)+p(I-1,J,K-1)) & ( 306) +c(I,J,K,1)*p(I-1,J,K) & ( 307) +c(I,J,K,2)*p(I,J-1,K) & ( 308) +c(I,J,K,3)*p(I,J,K-1)+wrk1(I,J,K) ( 309) ss=(s0*a(I,J,K,4)-p(I,J,K))*bnd(I,J,K) ( 310) GOSA=GOSA+SS*SS ( 311) wrk2(I,J,K)=p(I,J,K)+OMEGA *SS ( 312) enddo ( 313) enddo ( 314) enddo ----------------------- ~/Himeno> pgf90 -fast -Minfo=intensity himenoBMTxp.f90 jacobi: 292, Intensity = [symbolic], and not printable, try the -Mpfi -Mpfo options 294, Intensity = [symbolic], and not printable, try the -Mpfi -Mpfo options 295, Intensity = [symbolic], and not printable, try the -Mpfi -Mpfo options 296, Intensity = 1.06 コンパイル時に情報が特定できないループ情報(外側ループの情報)は、1度実行する。 まず、-Mpfi オプションを付してコンパイル&リンクします。 ~/Himeno> pgf90 -fast -Minfo=intensity himenoBMTxp.f90 -Mpfi ~/Himeno> ./a.out (実行) 実行後、pgfi.outと言う統計情報ファイルができます。これを元に再度、フィードバック コンパイル(-Mpfo) を行うと、以下のように外側ループの Intensity が出力されます。 ~/Himeno> pgf90 -fast -Minfo=intensity himenoBMTxp.f90 -Mpfo jacobi: 292, Intensity = 12.37 294, Intensity = 1.06 295, Intensity = 1.06 296, Intensity = 1.06
●コールグラフ対応実行モジュールの作成 pgfortran -fastsse -Mipa=cg -o a.out test.f ●コールグラフの出力(pgicgコマンドを使用) $pgicg -graph a.out (実行順番のコール・フロー) laplce_ . opnfil_ (opnfil.f:4) [74] . . pgf90io_src_info [15 18 23 26] . . pgf90io_open [15 23] . . pgf90io_ldw_init [18 26] . . pgf90io_ldw [18 26] . . pgf90io_ldw_end [18 26] . pgf90io_src_info [76 83] . pgf90io_ldw_init [76 83] . pgf90io_ldw [76 83] . pgf90io_ldw_end [76 83] . input_ (input.f:11) [80] . . pgf90io_src_info [18 20 25 27 37 38 39 45] . . pgf90io_ldr_init [18 25] . . pgf90io_ldr [18 25] . . pgf90io_ldr_end [18 25] . . pgf90io_ldw_init [20 27] . . pgf90io_ldw [20 27] . . pgf90io_ldw_end [20 27] . . pgf90io_fmtw_init [37 38 39 45] . . pgf90io_fmt_write [37 38 39 45] . . pgf90io_fmtw_end [37 38 39 45] . header_ (header.f:8) [87] . . pgf90io_src_info [12 13 14 15] . . pgf90io_fmtw_init [12 13 14 15] . . pgf90io_fmtw_end [12 13 14 15] . . pgf90io_fmt_write [13 14 15] . init_ (init.f:16) [100] . timer_ (timer.c:8) [104 113] . . gettimeofday [13] . solve_ (solve.f:14) [106] . error_ (error.f:8) [109] . swap_ (swap.f:8) [110] . verify_ (verify.f:18) [117] . epilog_ (epilog.f:13) [121] . . pgf90io_src_info [33 35 36 37 39 41 45 47 50 51] . . pgf90io_fmtw_init [33 35 36 37 39 41 45 47 50 51] . . pgf90io_fmtw_end [33 35 36 37 39 41 45 47 50 51] . . pgf90io_fmt_write [35 36 37 41 50 51] . clsfil_ (clsfil.f:3) [124] . . pgf90io_src_info [11 12] . . pgf90io_close [11 12] $pgicg -callers a.out clsfil_ (clsfil.f:3) called by laplce_ epilog_ (epilog.f:13) called by laplce_ error_ (error.f:8) called by laplce_ gettimeofday called by timer_ (timer.c:8) header_ (header.f:8) called by laplce_ init_ (init.f:16) called by laplce_ input_ (input.f:11) called by laplce_ laplce_ opnfil_ (opnfil.f:4) called by laplce_ pgf90io_close called by clsfil_ (clsfil.f:3) pgf90io_ldr called by input_ (input.f:11) pgf90io_ldr_end called by input_ (input.f:11) pgf90io_ldr_init called by input_ (input.f:11) pgf90io_ldw called by input_ (input.f:11) laplce_ opnfil_ (opnfil.f:4) pgf90io_ldw_end called by input_ (input.f:11) laplce_ opnfil_ (opnfil.f:4) pgf90io_ldw_init called by input_ (input.f:11) laplce_ opnfil_ (opnfil.f:4) pgf90io_open called by opnfil_ (opnfil.f:4) solve_ (solve.f:14) called by laplce_ swap_ (swap.f:8) called by laplce_ timer_ (timer.c:8) called by laplce_ verify_ (verify.f:18) called by laplce_ ●pgicg utility のその他のオプションのヘルプ $ pgicg -help Known Switches: -V Display version information -add={func} Add function to call graph; -add=func,size to change frame -addcall={func} Add calls; -addcall=f1,f2,f3 to add call from f2, f3 to f1 -allcallers[={func}] Print out all callers of function -allcallers Print out all callers of all functions -callers[={func}] Print out callers of function in path from main program -callers Print out callers of all functions -[no]demangle Do (don't) demangle C++ names -graph[={func}] Print out call graph starting at function -graph Prints out call graph starting at main routine -help Print out this help -nevercalled Print functions not called -notcalled Print functions not called in path from main program -remove={func} Remove function from call graph