「Message Passing Interface」の版間の差分

m
ブラッシュアップ
m (ブラッシュアップ)
 
*[http://mvapich.cse.ohio-state.edu/ MVAPICH]
*[http://www.microsoft.com/japan/technet/WindowsServer/library/4cb68e33-024b-4677-af36-28a1ebe9368f.mspx MS MPI]
 
通常、MPI 実装は以下のようなラッパーコンパイラを提供する:
 
* [[C言語|C]]: <code>mpicc</code>
* [[C++]]: <code>mpic++</code>, <code>mpicxx</code>
* [[Fortran]]: <code>mpif77</code>, <code>mpif90</code>, <code>mpifort</code>
 
<code>mpicc -show</code> ([[MPICH]] や Intel MPI) または <code>mpicc -showme</code> ([[Open MPI]]) を実行すると、実際に実行するコマンドを確認することができる。
 
プログラムの実行には <code>mpiexec</code> または <code>mpirun</code> を用いる。ノード間通信は [[リモートシェル|rsh]] や [[Secure Shell|ssh]]、あるいは[[ジョブ管理システム]]との連携により行う。
 
==プログラムの例==
 
<syntaxhighlight lang="c">
/* "Hello World" MPI テストプログラム */
/*
#include <stdiompi.h>
"Hello World" MPI テストプログラム
#include <stringstdio.h>
*/
#include <mpistring.h>
#include <stdio.h>
#include <string.h>
 
#define BUFSIZE 128
#define TAG 0
 
int main(int argc, char *argv[]) {
/* MPI は MPI_Initで開始環境を初期化する。これ以降、全 'N' プロセスが使える */
{
MPI_Init(&argc, &argv);
char idstr[32];
/* SPMD環境の規模全プロセス数を取得する */
char buff[BUFSIZE];
int numprocs;
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
int myid;
/* そしてこのプロセスのランク(番号)は)を取得する */
int i;
int myid;
MPI_Status stat;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* MPI は MPI_Initで開始する。これ以降、全 'N' プロセスが使える */
MPI_Init(&argc,&argv);
/* SPMD環境の規模を取得する */
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
/* そしてこのプロセスのランク(番号)は */
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
 
MPI_Status stat;
/* この時点で全プログラムは同等に走っており、SPMDモデルの中でこれらを区別する場合には
const int TAG = 0;
ランクで見分ける。ただしランク0のプログラムは特別な処理をしていることもある。... */
char idstr[32];
if(myid == 0)
char buff[BUFSIZE];
{
/* この時点で全プログラムは同等に走っており、SPMDモデルの中でこれらを区別する場合には
printf("%d: We have %d processors\n", myid, numprocs);
ランクで見分ける。ただしランク0のプログラムは特別な処理をしていることもある。... */
for(i=1;i<numprocs;i++)
{*/
if (myid == 0) {
sprintf(buff, "Hello %d! ", i);
printf("%d: We have %d processorsprocesses\n", myid, numprocs);
MPI_Send(buff, BUFSIZE, MPI_CHAR, i, TAG, MPI_COMM_WORLD);
for (int i = 1; i < numprocs; i++) {
}
sprintf(buff, "Hello %d! ", i);
for(i=1;i<numprocs;i++)
MPI_Send(buff, BUFSIZE, MPI_CHAR, i, TAG, MPI_COMM_WORLD);
{
int i;}
MPI_Recv(buff, BUFSIZE, MPI_CHAR, i, TAG, MPI_COMM_WORLD, &stat);
for (int i = 1; i < numprocs; i++) {
printf("%d: %s\n", myid, buff);
MPI_Recv(buff, BUFSIZE, MPI_CHAR, i, TAG, MPI_COMM_WORLD, &stat);
}
printf("%d: %s\n", myid, buff);
}
else }
} else {
/* rank 0から受信: */
MPI_Recv(buff, BUFSIZE, MPI_CHAR, 0, TAG, MPI_COMM_WORLD, &stat);
sprintf(idstr, "ProcessorProcess %d ", myid);
strncat(buff, idstr, BUFSIZE - 1);
strncat(buff, "reporting for duty", BUFSIZE - 1);
/* rank 0に送信: */
MPI_Send(buff, BUFSIZE, MPI_CHAR, 0, TAG, MPI_COMM_WORLD);
}
 
/* MPI FinalizeでMPIのプログラムは終了する。ここは弱い同期ポイント */
MPI_Finalize();
return 0;
}
</syntaxhighlight>
 
4 MPI プロセスでプログラムを実行する(<code>mpiexec -n 4 ./a.out</code>)と以下のような結果が得られる:
2プロセッサを使用してプログラムを実行すると以下のような結果が得られる<ref>OpenMPIで実行する場合は <code>gcc -g -v -I/usr/lib/openmpi/include/ -L/usr/lib/openmpi/include/ wiki_mpi_example.c -lmpi</code> のようにコンパイルして <code>mpirun -np 2 ./a.out</code>として実行する。</ref>。
 
<pre>
0: We have 24 processorsprocesses
0: Hello 1! ProcessorProcess 1 reporting for duty
0: Hello 2! Process 2 reporting for duty
0: Hello 3! Process 3 reporting for duty
</pre>