2012-05-13 8 views
2

CでMPIプログラミングに関する基本的な質問があります。基本的には、特定の数の子プロセスを生成し、すべてのプロセスから情報を収集するマスタープロセスがありますすべての子が終了するまで待機します)、このメトリックに基づいてメトリックを計算します。メトリックは、より多くのスレッドを生成する必要があるかどうかを判断します。メトリックが特定の条件を満たすまでこれを繰り返します。私は文献を検索して、役に立たない。これはどうすればできますか?任意のポインタ?C MPI - バッチ内で複数のスレッドを生成する

ありがとうございます。

礼儀:An introduction to the Message Passing Interface (MPI) using C。 「配列を合計するための完全な並列プログラム」では、「何らかの不自由な理由で」、マスタープロセスが配列の内容を2回合計したいとします。つまり、最初の反復では、マスタープロセスは、配列の合計を計算するスレーブプロセスを開始します。一度実行すると、マスタープロセスは値を返します。マスタープロセスを呼び出して、別のスレッドセットを再呼び出しして再び計算します。なぜ以下のコードはうまくいかないのでしょうか?スレーブプロセスを生成するマスタプロセスプロセスの周りにwhileループを追加しました。

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

    #define max_rows 100000 
    #define send_data_tag 2001 
    #define return_data_tag 2002 

    int array[max_rows]; 
    int array2[max_rows]; 

main(int argc, char **argv) 
{ 
    long int sum, partial_sum,number_of_times; 

    number_of_times=0; 

    MPI_Status status; 

    int my_id, root_process, ierr, i, num_rows, num_procs, 
    an_id, num_rows_to_receive, avg_rows_per_process, 
    sender, num_rows_received, start_row, end_row, num_rows_to_send; 

    /* Now replicte this process to create parallel processes. 
    * From this point on, every process executes a seperate copy 
    * of this program */ 

    ierr = MPI_Init(&argc, &argv); 

    root_process = 0; 

    /* find out MY process ID, and how many processes were started. */ 

    ierr = MPI_Comm_rank(MPI_COMM_WORLD, &my_id); 
    ierr = MPI_Comm_size(MPI_COMM_WORLD, &num_procs); 

    if(my_id == root_process) { 

    /* I must be the root process, so I will query the user 
     * to determine how many numbers to sum. */ 

    //printf("please enter the number of numbers to sum: "); 
    //scanf("%i", &num_rows); 

     num_rows=10; 

     while (number_of_times<2) 
     { 

     number_of_times++; 
     start_row=0; 
     end_row=0; 



    if(num_rows > max_rows) { 
     printf("Too many numbers.\n"); 
     exit(1); 
    } 

    avg_rows_per_process = num_rows/num_procs; 

    /* initialize an array */ 

    for(i = 0; i < num_rows; i++) { 
     array[i] = i + 1; 
    } 

    /* distribute a portion of the bector to each child process */ 

    for(an_id = 1; an_id < num_procs; an_id++) { 
     start_row = an_id*avg_rows_per_process + 1; 
     end_row = (an_id + 1)*avg_rows_per_process; 

     if((num_rows - end_row) < avg_rows_per_process) 
      end_row = num_rows - 1; 

     num_rows_to_send = end_row - start_row + 1; 

     ierr = MPI_Send(&num_rows_to_send, 1 , MPI_INT, 
       an_id, send_data_tag, MPI_COMM_WORLD); 

     ierr = MPI_Send(&array[start_row], num_rows_to_send, MPI_INT, 
       an_id, send_data_tag, MPI_COMM_WORLD); 
    } 

    /* and calculate the sum of the values in the segment assigned 
     * to the root process */ 

    sum = 0; 
    for(i = 0; i < avg_rows_per_process + 1; i++) { 
     sum += array[i]; 
    } 

    printf("sum %i calculated by root process\n", sum); 

    /* and, finally, I collet the partial sums from the slave processes, 
     * print them, and add them to the grand sum, and print it */ 

    for(an_id = 1; an_id < num_procs; an_id++) { 

     ierr = MPI_Recv(&partial_sum, 1, MPI_LONG, MPI_ANY_SOURCE, 
       return_data_tag, MPI_COMM_WORLD, &status); 

     sender = status.MPI_SOURCE; 

     printf("Partial sum %i returned from process %i\n", partial_sum, sender); 

     sum += partial_sum; 
    } 

    printf("The grand total is: %i\n", sum); 


     } 



    } 

    else { 

    /* I must be a slave process, so I must receive my array segment, 
     * storing it in a "local" array, array1. */ 

    ierr = MPI_Recv(&num_rows_to_receive, 1, MPI_INT, 
      root_process, send_data_tag, MPI_COMM_WORLD, &status); 

    ierr = MPI_Recv(&array2, num_rows_to_receive, MPI_INT, 
      root_process, send_data_tag, MPI_COMM_WORLD, &status); 

    num_rows_received = num_rows_to_receive; 

    /* Calculate the sum of my portion of the array */ 

    partial_sum = 0; 
    for(i = 0; i < num_rows_received; i++) { 
     partial_sum += array2[i]; 
    } 

    /* and finally, send my partial sum to hte root process */ 

    ierr = MPI_Send(&partial_sum, 1, MPI_LONG, root_process, 
      return_data_tag, MPI_COMM_WORLD); 
    } 


    ierr = MPI_Finalize(); 
} 
+0

コードはwhileループを追加しないで動作しますか?何が間違っていますか?セグメンテーションフォルトを持っていますか、プログラムが終了しないのか、それとも単に期待通りのことをしていませんか? – mort

+0

はい、そうです、whileループなしで正常に動作します...プログラムは最初のループを実行した後にハングします。 –

答えて

0

まず、MPI_Comm_spawnと集合操作を見てください。古い子プロセスから情報を収集するには、通常、MPI_Reduceを使用します。

This stackoverflow questionも役に立ちます。

...to spawn more threads... 

私はあなたがほとんどの代わりに「スレッド」の「プロセス」を使用しますが、ただ明確にするため、あなたが正しいことを意味推測:MPIはプロセスだけではなく、スレッドを扱っています。

私はMPIがどれほどよく知っているか分かりません。私の答えが助けになっているか、もっとヒントが必要なのかどうかを教えてください。

+0

ありがとうございました。私はMPIプログラミングの初心者です。あなたのような選手のおかげで、学習プロセスがスムーズになることを願っています。 –

+0

助けがあれば私の答えをupvoteしてください。私はフォローアップの質問に答えることがうれしいです。 – mort

+0

こんにちはモート、私はupvote(atleast thatsは、システムが言う)を使用するにはあまりにも若いので、私は現在upvoteできません。私がコードに添付しているコードスニペットを見てください。あなたは私がそれの問題を見つけるのを助けることができますか? –

0

MPI-2標準にはプロセス管理機能が含まれています。詳細はChapter 5に記載されています。私は自分自身でそれを使っていないので、おそらく他の人がより実用的なヒントで体重を測定するかもしれません。

関連する問題