2012-05-02 21 views
4

編集:私の質問はC, Open MPI: segmentation fault from call to MPI_Finalize(). Segfault does not always happen, especially with low numbers of processesに似ています。だから、あなたはそれに答えるのではなく、いずれにしても素晴らしいでしょう。 。 。MPIデバッグ、セグメンテーションフォルト?

私は次のコードをデバッグするいくつかの助けを得るために期待していた。

int main(){ 
     long* my_local; 
     long n, s, f; 
     MPI_Init(NULL, NULL); 
     MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); 
     MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 

    if(my_rank == 0){ 
     /* Get size n from user       */ 
     printf("Total processes: %d\n", comm_sz); 
     printf("Number of keys to be sorted? "); 
     fflush(stdout); 
     scanf("%ld", &n); 

     /* Broadcast size n to other processes    */ 
     MPI_Bcast(&n, 1, MPI_LONG, 0, MPI_COMM_WORLD); 

     /* Create n/comm_sz keys       
      NOTE! some processes will have 1 extra key if 
       n%comm_sz != 0        */ 
     create_Keys(&my_local, my_rank, comm_sz, n, &s, &f); 
    } 

    if(my_rank != 0){ 
     /* Receive n from process 0       */ 
     MPI_Bcast(&n, 1, MPI_LONG, 0, MPI_COMM_WORLD); 

     /* Create n/comm_sz keys       */ 
     create_Keys(&my_local, my_rank, comm_sz, n, &s, &f); 
    } 

     /* The offending function, f is a long set to num elements of my_local*/ 
     Odd_Even_Tsort(&my_local, my_rank, f, comm_sz); 

     printf("Process %d completed the function", my_rank); 
     MPI_Finalize(); 
     return 0; 
} 

void Odd_Even_Tsort(long** my_local, int my_rank, long my_size, int comm_sz) 
{ 
    long nochange = 1; 
    long phase = 0; 
    long complete = 1; 
    MPI_Status Stat; 
    long your_size = 1; 

    long* recv_buf = malloc(sizeof(long)*(my_size+1)); 
    printf("rank %d has size %ld\n", my_rank, my_size); 

    while (complete!=0){ 
     if((phase%2)==0){ 
      if(((my_rank%2)==0) && my_rank < comm_sz-1){ 
      /* Send right       */ 
       MPI_Send(&my_size, 1, MPI_LONG, my_rank+1, 0, MPI_COMM_WORLD); 
       MPI_Send(*my_local, my_size, MPI_LONG, my_rank+1, 0, MPI_COMM_WORLD); 
       MPI_Recv(&your_size, 1, MPI_LONG, my_rank+1, 0, MPI_COMM_WORLD, &Stat); 
       MPI_Recv(&recv_buf, your_size, MPI_LONG, my_rank+1, 0, MPI_COMM_WORLD, &Stat); 
      } 
      if(((my_rank%2)==1) && my_rank < comm_sz){ 
      /* Send left       */ 
       MPI_Recv(&your_size, 1, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD, &Stat); 
       MPI_Recv(&recv_buf, your_size, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD, &Stat); 
       MPI_Send(&my_size, 1, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD); 
       MPI_Send(*my_local, my_size, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD); 
      } 
     } 
     phase ++; 
     complete = 0; 
    } 

    printf("Done!\n"); 
    fflush(stdout); 
} 

を私は取得していますエラーは次のとおりです。

[ubuntu:04968] *** Process received signal *** 
[ubuntu:04968] Signal: Segmentation fault (11) 
[ubuntu:04968] Signal code: Address not mapped (1) 
[ubuntu:04968] Failing at address: 0xb 
-------------------------------------------------------------------------- 
mpiexec noticed that process rank 1 with PID 4968 on node ubuntu exited on signal 11 (Segmentation fault). 

私は困惑していた理由は、print文ということです機能がまだ表示された後、私は関数をコメントアウトする場合、エラーはありません。だから、ヒープのどこにセグメンテーションの欠陥があるのですか? mpiexec -n 2 ./a.outと9より大きい 'n'サイズのエラーが出ています。

実際に実行可能コード全体が必要だった場合は、教えてください。本当に私は正確な答えではなく、gdb/valgrindツールを使ってこの問題をデバッグする方法や、そのようなもの(そしてその出力を読む方法)をもっと望んでいました。

(はい、私は 'ソート'機能がまだソートされていないことを認識しています)。 MPI_Recvが呼び出されたコードで

ルック:

+0

"関数の後のprintステートメントは引き続き表示されますが、関数をコメントアウトするとエラーは発生しません"。これは、あなたの関数が何か間違っていることを示唆しており、後でエラーになります。障壁を置き、コードの重要な段階で印刷して、実行の距離を確認してください。 – suszterpatt

答えて

9

ここでの問題は単純で、まだデバッガを使用するか、徹底的なデバッグ情報をプリントアウトしない限り、参照することは困難です。 変数は、&recv_bufの代わりに引数として指定する必要があります。

MPI_Recv( recv_buf , your_size, MPI_LONG, my_rank-1, 0, MPI_COMM_WORLD, &Stat); 

残りは大丈夫です。

+0

ああ、ありがとう!これは、問題の根本が、配列自体のアドレスであるrecv_bufであることを意味しますが、&recv_bufはポインタrecv_bufのアドレスですか?私のCの経験はいくぶん限られていますので、あまりにも頻繁に何が混在する傾向があります。 – NickO

+0

@ニックはい、まさにその関係です。 –