2016-11-16 5 views
0

リングトポロジーを使用しMPI_REDUCE関数を使用してMPIでグローバル最大値を見つける効率テストを実行したいとします。私はすでに自分のコードでMPI_REDUCEをやっていますが、うまくいきますが、私はリングを渡して同じ結果を出したいと思っています。リングトポロジからのグローバルな最大値

私の考えは、各プロセッサのローカル最大値の配列を作成し、リングでこれらの最大値を渡し、最終的にグローバル最大値を出力することでした。

残念ながら、私はプロセスの最大値を保持する単一の配列を定義できないことに気付きました。むしろ、4つのプロセスから4つの異なる配列を生成しました。次に、rank = 0のプロセッサから始まる配列[0]の値を渡すことから始めました.4つの異なる配列を生成したときに、4つの異なる配列値を渡す必要があります。状況を悪化させるために、このような努力をしても、私はMPI_REDUCEコードの1行から得たグローバルな最大値を得られませんでした。リングトポロジーからグローバルな最大値を得る方法がなければならず、私は物事を複雑にしています。

次のようにコードの主要な部分がある:

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

    MPI_Init (&argc, &argv);  // initializes MPI 
    MPI_Comm_rank (MPI_COMM_WORLD, &rank); // get current MPI-process ID. O, 1, ... 
    MPI_Comm_size (MPI_COMM_WORLD, &size); // get the total number of processes  

    /* define how many integrals */ 
    const int n = 10;  

    double b[n] = {5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,5.0};      
    double a[n] = {-5.0, -5.0, -5.0, -5.0, -5.0, -5.0, -5.0, -5.0, -5.0,-5.0}; 

    double result, mean; 
    int m; 

    const unsigned int N = 5; 
    double max = 0; 
    double max_store[4]; 

    cout.precision(6); 
    cout.setf(ios::fixed | ios::showpoint); 

    srand(time(NULL) * rank); // each MPI process gets a unique seed 

    m = 4;    // initial number of intervals 

    // convert command-line input to N = number of points 
    //N = atoi(argv[1]); 
    for (unsigned int i=0; i <=N; i++) 
    { 
     result = int_mcnd(f, a, b, n, m); 
     mean = result/(pow(10,10)); 

     m = m*4; 
     if(mean > max) 
     { 
     max = mean; 
     } 
     if (rank < 4 && rank >= 0) 
     { 
     max_store[rank] = max; 
     }    
    } 

    //print the array containing max from each processor 
    for(int k = 0; k < 4; k++) 
    { 
    printf("%1.5e\n", max_store[k]); 
    } 

    printf("Process ID %i, local_max = %f\n",rank, max); 

    // All processes get the global max, stored in place of the local max 
    MPI_Allreduce(MPI_IN_PLACE, &max, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD); 

    printf("Process ID %d, global_max = %f\n",rank, max); 

    double send_junk = max_store[0]; 
    double rec_junk; 
    //double global_max; 
    MPI_Status status; 

    if(rank==0) 
    { 
    MPI_Send(&send_junk, 4, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD); // send data to process 1 
    } 
    if(rank==1) 
    { 
    MPI_Recv(&rec_junk, 4, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status); // receive data from process 0 
    } 
    //check between process 0 and process 1 maxima 
    if(rec_junk>=max_store[1]) 
    { 
    rec_junk = max_store[0]; 
    } 
    else 
    { 
    rec_junk = max_store[1]; 
    } 
    send_junk = rec_junk; 

    MPI_Send(&send_junk, 4, MPI_DOUBLE, 2, 0, MPI_COMM_WORLD); // send data to process 2 

    if(rank==2) 
    { 
    MPI_Recv(&rec_junk, 4, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD, &status); // receive data from process 1 
    } 
    //check between process 1 and process 2 maxima 
    if(rec_junk>=max_store[2]) 
    { 
    rec_junk = rec_junk; 
    } 
    else 
    { 
    rec_junk = max_store[2]; 
    } 
    send_junk = rec_junk; 

    MPI_Send(&send_junk, 4, MPI_DOUBLE, 3, 0, MPI_COMM_WORLD); // send data to process 3 

    if(rank==3) 
    { 
    MPI_Recv(&rec_junk, 4, MPI_DOUBLE, 2, 0, MPI_COMM_WORLD, &status); // receive data from process 2 
    } 
    //check between process 2 and process 3 maxima 
    if(rec_junk>=max_store[3]) 
    { 
    rec_junk = rec_junk; 
    } 
    else 
    { 
    rec_junk = max_store[3]; 
    } 

    printf("global ring max = %f", rec_junk); 

    MPI_Finalize(); // programs should always perform a "graceful" shutdown 
    return 0; 
} 

私は疑問を持っている:

  1. 私は印刷し、参照して、プロセスIDと極大値を簡単に、私はどのように保管しないことができます1つの配列の極大値?

  2. リングトポロジを使用してグローバルな最大値を見つけるより効率的な方法は何ですか?

あなたのご提案は大歓迎です。ありがとう

答えて

1

すべてのプロセスのローカル結果を1つの配列に集めるには、すべて0のプロセスにする場合はMPI_Gather、すべてのプロセスでそれらを取得する場合はMPI_Allgatherを使用します。

関連する問題