OCTOPUSで、IntelMPIを使ったノード間並列(分散メモリ並列)処理を行う方法を解説します。MPIを除く、Intelコンパイラの使い方や最適化については、こちらのページをご参照ください。

 

MPIとは

MPIとは、分散メモリ並列処理におけるメッセージパッシング(複数のプロセス間でデータをやり取りするために用いるメッセージ通信操作)の標準規格のことです。ノード間をまたがる並列化が可能となるため、その分大きなメモリ空間が利用可能になります。ただし、ユーザ自身で処理の分割やノード間の通信を指示する必要があるため、プログラミングの負担がやや大きくなります。
CとFORTRANで記述方法がやや異なりますが、本稿ではFORTRANを中心に説明します。

 

主な機能

MPIは以下のような機能を持っています。
・プロセスの管理
プログラムの初期化や終了処理を行います
・1対1の通信
1プロセス対1プロセスの通信操作
・集団の通信
グループ内のプロセス全体が関係する通信操作

 

基本的な利用方法

MPIプログラミングにかかる負担の多くはプログラムの「設計」に関するものであり、MPIを利用する為に覚えることはそんなに多くありません。本ページに書かれた、基本的な内容を習得するだけでも、十分利用することが可能です。

 

以下にFortranで書かれたMPIプログラムを載せています。こちらを参考に説明します。

 

プログラムのハイライト部分(2行目、4行目-6行目、8行目)が、MPIプログラム(MPIサブルーチン及びMPIに関連する処理)になります。5行目-7行目は、MPIの処理をPrint出力するために挿入した処理になりますので、入力しなくても、並列処理としての動きは変わりません。

 

2行目はMPI用のインクルードファイルの指定です。MPIを利用する場合、必ず指定してください。

 

プログラム中で「MPI_INIT」がcallされてから、「MPI_FINALIZE」がcallされるまでの区間がMPI並列の対象となり、MPI_INITがcallされた時点から、プロセスが生成されます。4行目と8行目がそれぞれ該当し、5~7行目の処理がマルチプロセスで実行されます。

 

5行目と6行目の「MPI_COMM_RANK」と「MPI_COMM_SIZE」はMPI処理の情報を得るためのサブルーチンです。「MPI_COMM_SIZE」では、処理を分割している数(並列プロセス数)を取得します。「MPI_COMM_RANK」では、分割された処理(並列プロセス)ごとにつけられた番号(プロセスID)を取得します。

 

並列プロセス数は、実行コマンド入力時に指定します。

 

上記のプログラムを、4プロセスで実行した結果は下記のようになります。

HELLO WORLD myrank= 3 ( 4 processes)
HELLO WORLD myrank= 1 ( 4 processes)
HELLO WORLD myrank= 0 ( 4 processes)
HELLO WORLD myrank= 2 ( 4 processes)

 

基本的なサブルーチンについて

 

MPI_INIT (ierr)

MPIを起動するコマンドです。
必ず他のMPIサブルーチンより前にコールしてください。

引数
ierr 正常終了時に0が格納されます。エラー時はそれ以外の値が格納されます。

 

MPI_FINALIZE (ierr)

MPIを終了するコマンドです。
必ず他のMPIサブルーチンより後にコールしてください。

引数
ierr 正常終了時に0が格納されます。エラー時はそれ以外の値が格納されます。

 

MPI_COMM_SIZE(comm, size, ierr)

引数「comm」で指定されたコミュニケータ(グループ)に含まれるプロセスの数の合計を取得する。
通常は「comm」に「MPI_COMM_WORLD」というMPI全プロセスを表すコミュニケータを指定し、
全プロセス数を取得するために使うことが多いのですが、複数のコミュニケータを使うことで、
複雑な処理を行うことが可能です。

引数
comm コミュニケータを指定します。前述の通り、通常はMPI全プロセスをあらわす「MPI_COMM_WORLD」を指定することが多いです。
size 取得したプロセス数の合計が格納されます。
ierr 正常終了時に0が格納されます。エラー時はそれ以外の値が格納されます

 

MPI_COMM_RANK(comm, size, ierr)

引数「comm」で指定されたコミュニケータ(グループ)内でプロセスごとにつけられた番号を取得する。
この番号のことを「プロセスID」「rank」と呼びます。
MPI_COMM_RANKと同じく、通常は「comm」に「MPI_COMM_WORLD」というMPI全プロセスを表すコミュニケータを指定することが多いです。

引数
comm コミュニケータを指定します。前述の通り、通常はMPI全プロセスをあらわす「MPI_COMM_WORLD」を指定することが多いです。
rank commで指定されたグループ内のプロセスID
ierr 正常終了時に0が格納されます。エラー時はそれ以外の値が格納されます

 

上記の例では、基本的なサブルーチンのみ用いておりますが、これら以外にも、さまざまなサブルーチンが用意されています。詳細は、下記の[参考資料]をご覧ください

 

コンパイル方法

プログラミング言語ごとにコマンドが異なりますので、ご注意ください。

$ mpiifort [options] source_file (Fortranの場合)
$ mpiicc [options] source_file (Cの場合)
$ mpiicpc [options] source_file (C++の場合)

利用可能なoptionについては、以下のページをご覧ください。

intelコンパイラ, intel MPIコンパイラの使い方

 

 

実行スクリプト

MPIを実行する際のコマンドは下記の通りです。

mpirun ${NQSII_MPIOPTS} -np (総並列数) 実行ファイル名

 

スクリプト例は下記の通りです。
4ノード並列実行、1ノードにつき24並列実行(計96並列実行)、経過時間 1時間でMPIのバッチリクエストを実行するスクリプトになります。

 
 

マルチノード実行時の注意点

ジョブスクリプトで「setenv (オプション名)」などでオプションや環境変数を指定した場合、マスターノードにのみ設定され、スレーブノードには設定されません。
全ノードに設定を反映させたい場合は「#PBS -v (オプション名)」と指定してください。
詳細は下記に記載しております。
ジョブスクリプトの書き方 環境変数の指定

 

 

参考資料

Intel® MPI Library Developer Guide
Intel® MPI Library Developer Reference
Getting Started with Intel® MPI Library