2017-01-23 8 views
1

私がしようとしているのは1と0の配列を作り、配列全体を4つのプロセスに分割することですテストケースは4つです)、各プロセスにランク、配列の長さ、配列自体を出力させます。しかし、コードを実行すると、次のようなものが得られます。何らかの理由で私の他のプロセスが私の最初のプロセス(CのMPI)からデータを受け取りません

Enter length and sequence length 
100 4 
1101000010110110101110101 
1110101001111100011100100 
1011100110011100001011010 
1000110101001000001000111 

Rank: 0 Length: 25 

これはどうして起こるのかわかりません。私は他のプロセスに適切にデータを渡すことはできません何らかの理由で(私はMPIに非常に新しいです)

のためにここに私のコードは次のとおりです。私が修正したフィードバック用

#include "ore_header.h" 

int main(int argc, char** argv) { 

srand(time(NULL)); 

    int  my_rank, p; 
    int  total; 
    int  length; 
    int  seq_length; 
    void generate_sequence(int *arr, int n); 
    int  subsequence_check(int *arr,int n, int m); 


    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &p); 
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 

    MPI_Request  reqs[p]; 
    MPI_Status  stats[p]; 
    int  p_length; 
    int  p_total[p]; 
    int  *buf[p]; 
    if (my_rank == 0) { 
     printf("Enter length and sequence length\n"); 
     scanf("%d %d",&length, &seq_length); 
     p_length = length/p; 
     for (int i = 0; i < p; i++) { 
      buf[i] = (int*)malloc(p_length*sizeof(int)); 
      generate_sequence(buf[i], p_length); //Generates a sequence 
      MPI_Isend(&buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]); //Send each buffer to each sequence 
      MPI_Wait(&reqs[my_rank], &stats[my_rank]); //Wait for data to be sent 
     } 
    } 
    MPI_Irecv(&buf[my_rank], p_length, MPI_INT, 0, 0, MPI_COMM_WORLD, &reqs[my_rank]); //Receive Data from process 0 
    MPI_Wait(&reqs[my_rank], &stats[my_rank]); //Wait for communication to end 
    printf("\nRank: %d Length: %d\n",my_rank,p_length); 
    for (int i = 0; i < p_length; i++) { 
     printf("%d",buf[i]); 
    } 

    //tot = subsequence_check(buf,length,seq_length); 
    //printf("\n\nTotal: %d\n",tot); 
    MPI_Finalize(); 
    return (0); 
} 

UPDATE

感謝問題と意図したように、今では動作します:

#include "ore_header.h" 

int main(int argc, char** argv) { 

    srand(time(NULL)); 

    int  my_rank, p; 
    int  total; 
    int  length; 
    int  flag; 
    int  seq_length; 
    void generate_sequence(int *arr, int n); 
    int  subsequence_check(int *arr,int n, int m); 


    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &p); 
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 


    int  p_length; 
    int  *buf[p]; 
    if (my_rank == 0) { 
     printf("Enter length and sequence length\n"); 
     scanf("%d %d",&length, &seq_length); 
     p_length = length/p; 
     for (int i = 0; i < p; i++) { 
      buf[i] = (int*)malloc(p_length*sizeof(int)); 
      generate_sequence(buf[i], p_length); 
      MPI_Send(buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD); 
      printf("Data sent to process %d\n", i); 
     } 
    } 
    MPI_Bcast(&p_length, 1, MPI_INT, 0, MPI_COMM_WORLD); 
    buf[my_rank] = (int*)malloc(p_length*sizeof(int)); 
    MPI_Status  stats[p]; 
    MPI_Request  reqs[p]; 
    MPI_Irecv(buf[my_rank], p_length, MPI_INT, 0, 0, MPI_COMM_WORLD, &reqs[my_rank]); 
    while(1) { 
     MPI_Test(&reqs[my_rank], &flag, &stats[my_rank]); 
     if (flag) break; 
    } 
    printf("\nData received on process: %d Length: %d\n",my_rank,p_length); 
    for (int i = 0; i < p_length; i++) { 
     printf("%d",buf[my_rank][i]); 
    } 
    printf("\n"); 

    //tot = subsequence_check(buf,length,seq_length); 
    //printf("\n\nTotal: %d\n",tot); 
    MPI_Finalize(); 
    return (0); 
} 

、ここでは私の出力です:

Enter length and sequence length 
100 4 
0101100011001110110010011 
Data sent to process 0 
0010011010000001001010111 
Data sent to process 1 
0011111111101101100000111 
Data sent to process 2 
0000000100010011100001111 
Data sent to process 3 

Data received on process: 0 Length: 25 
0101100011001110110010011 

Data received on process: 1 Length: 25 
0010011010000001001010111 

Data received on process: 2 Length: 25 
0011111111101101100000111 

Data received on process: 3 Length: 25 
0000000100010011100001111 
+2

'p_length'の値は' MPI_Irecv'ing何ですか? – a3f

+0

長さをnとすると、p_lengthはn \ pです。ここでpはプロセス数です – Malush

+1

もう一度チェックしてください。 :) – a3f

答えて

0

MPI_Isend()はバッファへのポインタを必要とし、&buf[i]はバッファへのポインタへのポインタである。したがって、MPI_Isend(buf[i],...をお試しいただけますか?

さらに、reqs[i]の要求はMPI_Isend()に設定されていますが、MPI_Wait()reqs[my_rank]の完了をチェックするだけです。そのため、他の変形例を提案することができます。

MPI_Isend(buf[i], p_length, MPI_INT, i, 0, MPI_COMM_WORLD, &reqs[i]); //Send each buffer to each sequence 
MPI_Wait(&reqs[i], &stats[i]); //Wait for data to be sent 

呼び出すMPI_Wait()MPI_Isend()後に返さMPI_StatusがMPI_Test_cancelled()ような何かによってテストされていない場合は特に、MPI_Send()を呼び出すのと同じようです。この場合、MPI_Wait()への連続呼び出しは、forループの最後にMPI_Waitall()への1回の呼び出しで簡単に置き換えることができます。

編集:0がまだ有効であるよりも、他のランクにMPI_Irecv()p_lengthの値にA3F @の質問...

+0

お返事いただきありがとうございます。なぜ私の&buf [i]がうまくいかなかったのか説明できますか?私はbuf [i]がポインタの値を保持していると思いましたか?またはポインタのアドレスを保持していますか? – Malush

+0

'buf [i]'はバッファの最初の項目である 'buf [i] [0]'へのポインタです:その値は 'buf [i] [0]'のアドレスです。これはまさに 'MPI_Isend()'が必要とするものです。逆に、 '&buf [i]'はポインタ 'buf [i]'へのポインタです。その値は 'buf [i]'のアドレスであり、バッファの最初の項目ではありません。 '&buf [i]'はバッファへのポインタへのポインタです。それはあまりにも1つのポインタです! – francis

+0

入手しました。ありがとう! – Malush

関連する問題