Looking for mpi Answers? Try Ask4KnowledgeBase
Looking for mpi Keywords? Try Ask4Keywords

mpimpiを使い始める


備考

MPIは、分散(またはローカル)プロセスのグループ間の通信の標準です。データを送受信するルーチン、一括して通信するルーチン、およびその他のより複雑なタスクが含まれています。

この標準はCとFortranのAPIを提供しますが、他のさまざまな言語へのバインディングも存在します。

バージョン

バージョン標準発売日
1 mpi-report-1.3-2008-05-30.pdf 1994-05-05
2.0 mpi2-report.pdf 2003-09-15
2.2 mpi22-report.pdf 2009-09-04
3.0 mpi30-report.pdf 2012-09-21
3.1 mpi31-report.pdf 2015-06-04

"こんにちは世界"

MPIの使い方を学ぶときには、通常3つのことが重要です。まず、ライブラリを使用する準備ができたらライブラリを初期化する必要があります(完了したらライブラリを完成させる必要があります)。次に、コミュニケータのサイズ(他のプロセスにメッセージを送信するために使用するもの)を知りたい場合があります。第三に、そのコミュニケータの中のあなたのランクを知りたいでしょう(プロセス番号はそのコミュニケータの中にいます)。

#include <mpi.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int size, rank;
    int res;

    res = MPI_Init(&argc, &argv);
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Init failed\n");
        exit (0);
    }

    res = MPI_Comm_size(MPI_COMM_WORLD, &size);
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Comm_size failed\n");
        exit (0);
    }
    res = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Comm_rank failed\n");
        exit (0);
    }

    fprintf(stdout, "Hello World from rank %d of %d~\n", rank, size);

    res = MPI_Finalize();
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Finalize failed\n");
        exit (0);
    }
}
 

このようにこのプログラムを実行すると:

mpiexec -n 2 ./hello
 

次のような出力が得られます。

Hello World from rank 0 of 2!
Hello World from rank 1 of 2!
 

これについての詳細は、出力を後で取得することもできます( http://stackoverflow.com/a/17571699/491687を参照 )。

Hello World from rank 1 of 2!
Hello World from rank 0 of 2!
 

Init / Finalize

MPIコマンドを実行する前に、環境を初期化し、最後にファイナライズする必要があります。

int main(int argc, char** argv)
{
    int res;
    res = MPI_Init(&argc,&argv);
    if (res != MPI_SUCCESS)
    {
      fprintf (stderr, "MPI_Init failed\n");
      exit (0);
    }
    ...
    res = MPI_Finalize();
    if (res != MPI_SUCCESS)
    {
      fprintf (stderr, "MPI_Finalize failed\n");
      exit (0);
    }
}
 

ランクとサイズ

コミュニケータ(例えばMPI_COMM_WORLD )のサイズとローカルプロセスのランクを取得するには:

int rank, size;
int res;
MPI_Comm communicator = MPI_COMM_WORLD;

res = MPI_Comm_rank (communicator, &rank);
if (res != MPI_SUCCESS)
{
  fprintf (stderr, "MPI_Comm_rank failed\n");
  exit (0);
}
res = MPI_Comm_size (communicator, &size);
if (res != MPI_SUCCESS)
{
  fprintf (stderr, "MPI_Comm_size failed\n");
  exit (0);
}
 

MPI呼び出しの戻り値

ほぼすべてのMPI呼び出しは、操作の成功を示す整数エラーコードを返します。エラーが発生しない場合、戻りコードはMPI_SUCCESS です。

if (MPI_Some_op(...) != MPI_SUCCESS)
{
   // Process error
}
 

エラーが発生した場合、MPIは、ユーザーコードに戻る前に、コミュニケータ、ウィンドウまたはファイルオブジェクトに関連付けられたエラーハンドラを呼び出します。あらかじめ定義された2つのエラーハンドラがあります(ユーザは追加のエラーハンドラを定義できます)。

  • MPI_ERRORS_ARE_FATAL - エラーによりMPIプログラムが終了する
  • MPI_ERRORS_RETURN - エラーによりエラーコードがユーザーに返されます

コミュニケータとウィンドウのデフォルトのエラーハンドラはMPI_ERRORS_ARE_FATAL です。ファイルオブジェクトの場合はMPI_ERRORS_RETURN です。 MPI_COMM_WORLD のエラーハンドラは、オブジェクトに特に関連しないすべての操作(たとえば、 MPI_Get_count )にも適用されます。したがって、エラーハンドラをMPI_ERRORS_RETURN 設定せずに非I / O操作の戻り値をチェックすることは、誤ったMPI呼び出しが返されないため、冗長です。

// The execution will not reach past the following line in case of error
int res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
    // The following code will never get executed
    fprintf(stderr, "MPI_Comm_size failed: %d\n", res);
    exit(EXIT_FAILURE);
}
 

ユーザーエラー処理を有効にするには、 MPI_COMM_WORLD エラーハンドラを変更する必要があります。

MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);

int res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
    fprintf(stderr, "MPI_Comm_size failed: %d\n", res);
    exit(EXIT_FAILURE);
}
 

MPI標準では、MPI実装がエラーから回復してプログラムの実行を続けることは要求されません。