PGIコンパイラ利用法
最終更新日:2020年9月30日
PGIコンパイラはPGI社の提供するC/C++, Fortran向けのコンパイラです。
ここでは、主にプログラミング言語 Fortran, C, C++の翻訳・実行方法とバッチ処理方法について解説します。
PGIコンパイラはCUDA FortranやOpenACC向けのコンパイラとしても利用可能です。
これらについては個別のページの説明をご確認ください。
利用環境
システム・バージョン・利用範囲
- サブシステムA
バージョン |
九州大学構成員 |
学術研究機関構成員 |
民間利用の方 |
17.7 |
〇 |
- |
- |
- サブシステムB
バージョン |
九州大学構成員 |
学術研究機関構成員 |
民間利用の方 |
17.7 |
〇 |
- |
- |
19.9 |
〇 |
- |
- |
- 基本フロントエンド
バージョン |
九州大学構成員 |
学術研究機関構成員 |
民間利用の方 |
17.7 |
〇 |
- |
- |
19.9 |
〇 |
- |
- |
- 大容量フロントエンド
バージョン |
九州大学構成員 |
学術研究機関構成員 |
民間利用の方 |
17.7 |
〇 |
- |
- |
19.9 |
〇 |
- |
- |
ITOシステムにインストールされているPGIコンパイラ(CUDA Fortran, OpenACCを含む)は、 ライセンスの都合上、九州大学の構成員でなければ利用できません。 また、このコンパイラの最新版は ITOでは利用できません。
九州大学の構成員以外の方や、より新しいバージョンの PGIコンパイラを試したい方は、
NVIDIA HPC SDK
の利用をご検討ください。
利用コマンド
プログラム言語の翻訳・リンクのための書式とコマンドの一覧は以下の通りです。
|
言語処理系 |
コマンド |
OpenMP* |
非MPI並列 |
Fortran |
pgfortran |
-mp |
C |
pgcc |
C++ |
pgc++ |
MPI並列 |
Fortran |
mpifort |
C |
mpicc |
C++ |
mpic++ |
* OpenMPオプションはデフォルトでは無効です。
利用方法
環境設定(moduleコマンド)
moduleコマンドによる環境設定はコンパイル時と実行時の両方で行う必要があります。
pgi 17.7を使用する場合の例)
pgi 19.9を使用する場合の例)
PGIに内包された Open MPIを用いる場合は、以下も実行してください。
pgi 17.7を使用する場合の例)
$ module load pgi/17.7_openmpi |
pgi 19.9を使用する場合の例)
$ module load pgi/19.9_openmpi |
C/C++
C/C++コンパイラは pgcc
/ pgc++
コマンドを利用します。
PGIに内包された Open MPIを使用する場合はmpicc
/ mpic++
を利用します。
(以下のプログラム例では pgcc
およびmpicc
のみを記載しますのでC++を使う場合はpgc++
およびmpic++
に読み替えてください。)
例1)逐次プログラム
$ pgcc -fast -tp=haswell sample.c |
例2)ノード内スレッド並列(OpenMP)プログラム
$ pgcc -fast -mp -tp=haswell sample.c |
例3)MPI並列(フラットMPI)プログラム
$ mpicc -fast -tp=haswell sample.c |
例4)ハイブリッド並列(OpenMP+MPI)プログラム
$ mpicc -fast -mp -tp=haswell sample.c |
Fortran
Fortranコンパイラは pgfortran
コマンドを利用します。
MPIライブラリを使用する場合はmpifort
コマンドを利用します。
pgf77/pgf90やmpif77/mpif90など、Fortranのバージョンに合わせたコマンドも存在しますが、
特別な事情のない限りpgfortranとmpifortさえ使用すれば十分です。
例1)逐次プログラム
$ pgfortran -fast -tp=haswell sample.f90 |
例2)ノード内スレッド並列(OpenMP)プログラム
$ pgfortan -fast -mp -tp=haswell sample.f90 |
例3)MPI並列(フラットMPI)プログラム
$ mpifort -fast -tp=haswell sample.f90 |
例4)ハイブリッド並列(OpenMP+MPI)プログラム
$ mpifort -fast -mp -tp=haswell sample.f90 |
主な翻訳時オプション
翻訳時オプション |
説明 |
-c |
オブジェクトファイルまで生成 |
-o exe_file |
実行可能ファイル名/オブジェクトファイル名をexe_fileに変更
実行可能ファイル名を省略した場合にはa.out
|
-O[0, 1, 2, 3, 4] |
最適化レベルを指定。-Oの後の数字を省略した場合は-O1に近いレベルとなる。 |
-fast |
高速化のための最適化オプションを誘導(最適化での推奨オプション) |
-mp |
OpenMPディレクティブを有効化。 |
-I directory |
インクルードファイル、モジュールファイルを検索するディレクトリを指定 |
-Mfixed (Fortranのみ) |
ソースコードが固定形式で記述されていることを指定 |
-Mfree (Fortranのみ) |
ソースコードが自由形式で記述されていることを指定 |
-cpp または -Mpreprocess |
プリプロセス処理を行う |
-Minfo=options |
optionsで指定した種類の最適化情報を出力する。allで全て、mpでOpenMPに関する情報のみを出力など。 |
-tp=architecture |
architectureで指定したアーキテクチャ(およびそれ以上)のCPU向けのコード生成を行う。ITOシステムではhaswellを指定する。
(Community Editionの PGIコンパイラ、バージョン 18.1以降を利用する場合は、skylakeを指定する。)) |
-c99 および -c11 (Cのみ) |
C99規格およびC11規格に基づいたコンパイル処理を行う |
-help |
コンパイルオプションの一覧を表示 |
-V |
コンパイラのバージョン情報を出力 |
推奨オプション以外の最適化機能は、プログラムデータの特性によって効果がある場合と、そうでない場合があり、実際に動作させて検証する必要があります。
推奨オプションを指定すると、関連して複数の最適化オプションが誘導されます。
Fortran, C/C++の標準的なオプションとして、-fast
を推奨します。
数値計算ライブラリ
PGIコンパイラから利用できる数値演算ライブラリに
LAPACK, BLAS, FFTがあります。
さらにMPIライブラリからはScaLAPACKも利用できます。
コンパイル時にそれぞれ-llapack
, -lblas
, -fft
, -Mscalapack
オプションを付けてください。
バッチ処理
ITOのサブシステム A/BでPGIコンパイラで作成した実行可能ファイル(モジュール)を実行するためには、
「バッチ処理」と呼ばれる手続きにより計算サーバーに処理の依頼をする必要があります。
バッチ処理の詳細は バッチ処理を参照してください。
以下にPGIコンパイラで翻訳した実行可能ファイルをバッチ処理により処理するスクリプトの例を示します。
例1)逐次プログラム
仮想ノード数
|
:1ノード(1プロセス) |
仮想ノード当たりのコア数(スレッド数)
|
:1コア(1スレッド)(リソースグループの利用可能コア数を指定) |
最大経過時間
|
:10分 |
標準エラー出力と標準出力を同じファイルに保存
|
:あり |
ジョブリソースグループ(キュー)
|
:ito-single |
#!/bin/bash
#PJM -L "rscunit=ito-a"
#PJM -L "rscgrp=ito-single"
#PJM -L "vnode=1"
#PJM -L "vnode-core=1"
#PJM -L "elapse=10:00"
#PJM -j
#PJM -X
module load pgi/17.7
./a.out
|
|
サブシステム名(ito-a)の指定
リソースグループ(ito-single)の指定
仮想ノード数を指定
仮想ノードあたりのコア数を指定
最大経過時間の指定
標準エラー出力を標準出力に重ねる
ジョブ投入時の環境変数をジョブ実行環境に継承
環境設定
ジョブの実行
|
|
例2)ノード内スレッド並列(OpenMP)プログラム
仮想ノード数
|
:1ノード(1プロセス) |
仮想ノード当たりのコア数(スレッド数)
|
:36コア(36スレッド)(リソースグループの利用可能コア数を指定) |
最大経過時間
|
:10分 |
標準エラー出力と標準出力を同じファイルに保存
|
:あり |
ジョブリソースグループ(キュー)
|
:ito-ss-dbg |
#!/bin/bash
#PJM -L "rscunit=ito-a"
#PJM -L "rscgrp=ito-ss-dbg"
#PJM -L "vnode=1"
#PJM -L "vnode-core=36"
#PJM -L "elapse=10:00"
#PJM -j
#PJM -X
module load pgi/17.7
export OMP_NUM_THREADS=36
./a.out
|
|
サブシステム名(ito-a)の指定
リソースグループ(ito-ss-dbg)の指定
仮想ノード数を指定
仮想ノードあたりのコア数を指定(リソースグループの利用可能コア数を指定)
最大経過時間の指定
標準エラー出力を標準出力に重ねる
ジョブ投入時の環境変数をジョブ実行環境に継承
環境設定
スレッド数の指定
ジョブの実行
|
|
例3)フラットMPI並列プログラム
プロセス数
|
:144プロセス |
物理ノード数(仮想ノード数)
|
:4ノード |
プロセスの割り当て
|
:1ノードあたり36プロセス |
最大経過時間
|
:10分 |
標準エラー出力と標準出力を同じファイルに保存
|
:あり |
ジョブリソースグループ(キュー)
|
:ito-s-dbg |
#!/bin/bash
#PJM -L "rscunit=ito-a"
#PJM -L "rscgrp=ito-s-dbg"
#PJM -L "vnode=4"
#PJM -L "vnode-core=36"
#PJM -L "elapse=10:00"
#PJM -j
#PJM -X
module load pgi/17.7_openmpi
mpirun -n 144 -map-by ppr:36:node --bind-to none -mca plm_rsh_agent /bin/pjrsh -machinefile ${PJM_O_NODEINF} ./a.out
|
|
サブシステム(ito-a)の指定
リソースグループ(ito-s-dbg)の指定
仮想ノード数(物理ノード数)を指定
仮想ノードあたりのコア数を指定(= 物理ノード当たりのコア数を指定)
最大経過時間の指定
標準エラー出力を標準出力に重ねる
ジョブ投入時の環境変数をジョブ実行環境に継承
環境設定
MPIプログラムを起動
|
|
例4)ハイブリッド並列化プログラム
プロセス数
|
:16プロセス |
1プロセスあたりのスレッド数
|
:9スレッド |
物理ノード数(仮想ノード数)
|
:4ノード |
プロセスの割り当て
|
:1ノードあたり4プロセス |
最大経過時間
|
:10分 |
標準エラー出力と標準出力を同じファイルに保存
|
:あり |
ジョブリソースグループ(キュー)
|
:ito-s-dbg |
#!/bin/bash
#PJM -L "rscunit=ito-a"
#PJM -L "rscgrp=ito-s-dbg"
#PJM -L "vnode=4"
#PJM -L "vnode-core=36"
#PJM -L "elapse=10:00"
#PJM -j
#PJM -X
module load pgi/17.7_openmpi
export OMP_NUM_THREADS=9
mpirun -n 16 -map-by ppr:4:node --bind-to none -mca plm_rsh_agent /bin/pjrsh -machinefile ${PJM_O_NODEINF} ./a.out
|
|
サブシステム(ito-a)の指定
リソースグループ(ito-s-dbg)の指定
仮想ノード数(物理ノード数)を指定
仮想ノードあたりのコア数を指定
最大経過時間の指定
標準エラー出力を標準出力に重ねる
ジョブ投入時の環境変数をジョブ実行環境に継承
環境設定
OpenMPスレッド並列数を設定
MPIプログラムを起動
|
|
Open MPIの詳細な利用方法は以下を確認してください。
Open MPI Documentation
Open MPIによるプロセスのノードへの割り当て指定
以下は、Open MPIでプロセスをノードに割り当てる方針を指定する例です。
-display-devel-map は、割当の結果を表示するオプションです
# 1ソケットに1プロセス、合計2プロセスの例(1ノードで2プロセス並列実行をする想定)
mpirun -n 2 -display-devel-map -map-by ppr:1:socket --mca plm_rsh_agent /bin/pjrsh -machinefile ${PJM_O_NODEINF} ./a.out
# 1ノードに1プロセス、合計2プロセスの例(2ノードで2プロセス並列実行をする想定)
mpirun -n 2 -display-devel-map -map-by ppr:1:node --mca plm_rsh_agent /bin/pjrsh -machinefile ${PJM_O_NODEINF} ./a.out
# 1ノードに2プロセス、合計4プロセスの例(2ノードで4プロセス並列実行をする想定)
mpirun -n 4 -display-devel-map -map-by ppr:1:socket --mca plm_rsh_agent /bin/pjrsh -machinefile ${PJM_O_NODEINF} ./a.out
mpirun -n 4 -display-devel-map -map-by ppr:2:node --mca plm_rsh_agent /bin/pjrsh -machinefile ${PJM_O_NODEINF} ./a.out
# 上記の2つのmpirunは厳密には意味が異なりますが、
# どちらも1つ目のノードの2ソケットに1プロセスずつ割り当てた後に2つ目のノードの2ソケットに1プロセスずつ割り当てられます。
# ノードを交互に使いたい(1つ目のノードにプロセス0と2、2つ目のノードにプロセス1と3、としたい)場合は
# --rank-by nodeというオプションを追加してください
|
参考資料