1

数値積分関数を並列化したい。計算の途中でこの関数を使いたいです。前の作業はルートプロセスで行う必要があります。これはMPIで行うことができますか?

 double integral_count_MPI(double (*function)(double) , double beginX, double endX, int      count)
 {
    double step, result;
    int i;
    if (endX - beginX <= 0) return 0;
    step = (endX - beginX) / count;
    result = 0;

    double *input = (double*)malloc((count+1) *sizeof(double));
    for (i = 0; i <= count; i ++)
    {
       input[i] = beginX + i*step;
    }
    // Calculate and gather
 }

編集

アルゴリズム:

  1 process calculation;
while:
  1 process calculation;
  integration very complex function with many processes;
  1 process calculation;
end while;
1 process calculation;
4

2 に答える 2

3

MPIは、「舞台裏」でMPIを使用するライブラリを構築するためのさまざまな手段を提供します。手始めに、MPIをオンデマンドで初期化できます。MPI-2は、呼び出しの要件を変更して、準拠するすべての実装がへの引数MPI_Initで正しく初期化できるようにしました(実際のプログラム引数がライブラリで使用できない場合があるため)。MPIは一度だけ初期化する必要があるため、ライブラリはを呼び出して、MPIがすでに初期化されているかどうかを確認する必要があります。コードは基本的に次のようになります。NULLMPI_InitMPI_Initialized

void library_init(void)
{
   int flag;

   MPI_Initialized(&flag);
   if (!inited)
   {
      MPI_Init(NULL, NULL);
      atexit(library_onexit);
   }
}

atexit()初期化コードは、C標準ライブラリから呼び出すことによって出口ハンドラーも登録します。この出口ハンドラー内で、MPIライブラリーがまだファイナライズされていない場合はファイナライズします。そうしないmpiexecと、MPIを終了せずに、少なくとも1つのプロセスが終了したというメッセージが表示されてMPIジョブ全体が終了する可能性があります。

void library_onexit(void)
{
   int flag;

   MPI_Finalized(&flag);
   if (!flag)
      MPI_Finalize();
}

integral_count_MPIこの配置により、関数を次のように簡単に記述できます。

double integral_count_MPI(...)
{
    library_init();

    ... MPI computations ...
}

integral_count_MPI最初の呼び出しでMPIライブラリを要求初期化します。library_init後の呼び出しでは、方法が記述されているため、再初期化は行われません。また、明示的なファイナライズは必要ありません。出口ハンドラーが処理します。

コードのシリアル部分は各インスタンスで実行されるため、MPIプロセスランチャー(、など)を介してコードを起動する必要があり、mpirunI /Oの実行には注意する必要があることに注意してください。mpiexec多くのMPI対応ライブラリは、その目的のために独自のI / Oルーチンを提供し、プロセスランクでフィルタリングし、ランク0のみが実際のI/Oを実行できるようにします。MPIの動的プロセス管理機能を使用して、オンデマンドで追加のプロセスを生成することもできますが、統合を実行するライブラリにプロセス管理の大部分を抽象化する必要があり、非常に複雑になります(およびコードあなたのメインプログラムのはぎこちなく見えるでしょう)。

于 2012-12-16T13:16:29.997 に答える
2

MPI ドキュメントはここにあります。

基本的に、ロジックは次のとおりです。

int main()
{
    MPI_INIT(...);
    MPI_Comm_size(...);    //get the number of processes
    MPI_Comm_rank(...);    //get my rank

    if (rank == 0)     //master process
    {
        for (i = 1; i < n; i++)
            MPI_Send(...) //Send interval data specific to i process

        double result = 0;
        for (i = 1; i < n; i++)
        {
            double part_result;

            MPI_Recv(&part_result, ...) //Receive partial results from slaves

            result += part_result;
        }

        // Print result
    }
    else               //slave process
    {
        MPI_Recv(...)  //Receive interval data from master (rank 0 process)

        double result = integral_count_MPI(...);

        MPI_Send(...)  // Send results to master
    }

    MPI_FINALIZE(...);
}
于 2012-12-16T11:21:21.703 に答える