2017-04-04 7 views
0

私はMPIとCを使ってプログラミングしています。ルートランクを使用してファイルからデータを読み取り、それを残りのランクに配布しています。私のMPI_Scatterは正常に動作し、値が正しいことを確認するために値を出力します。私の問題は、構造体を割り当てた後、ルートランク以外のランクからそれらにアクセスしようとするときにエラーが発生することです。MPI_Scatter()の後にmallocが続くsegfault

pr_graph * graph = malloc(sizeof(*graph)); 
    .... 

    MPI_Scatter(verticesCountArray, 1, MPI_INT, &(graph->nvtxs), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 
    MPI_Scatter(edgesCountArray, 1, MPI_INT, &(graph->nedges), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 

    for(int rank = 0; rank<numProcesses; rank++){ 
     if (rank == myrank){ 
     fprintf(stderr, "%d %d \n",graph->nvtxs, graph->nedges); 
     graph->xadj = malloc((graph->nvtxs + 1) * sizeof(*graph->xadj)); 
     graph->nbrs = malloc(graph->nedges * sizeof(*graph->nbrs)); 
     // graph->xadj[graph->nvtxs] = graph->nedges; 

     } 
     MPI_Barrier(MPI_COMM_WORLD); 
    } 

そして、私の出力は次のようになります。正しい

2 4 
    2 4 
    2 4 

。私はコメント行のコメントを解除する場合でも、私が手:

2 4 
    2 4 
    [phi01:07170] *** Process received signal *** 
    [phi01:07170] Signal: Segmentation fault (11) 
    [phi01:07170] Signal code: (128) 
    [phi01:07170] Failing at address: (nil) 
    [phi01:07170] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f5740503390] 
    [phi01:07170] [ 1] ./pagerank[0x401188] 
    [phi01:07170] [ 2] ./pagerank[0x400c73] 
    [phi01:07170] [ 3] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f5740149830] 
    [phi01:07170] [ 4] ./pagerank[0x400ce9] 
    [phi01:07170] *** End of error message *** 
    -------------------------------------------------------------------------- 
    mpirun noticed that process rank 1 with PID 7170 on node phi01 exited on signal 11 (Segmentation fault). 

のみランク0は、それが割り当てられた構造にアクセスできることを意味しています。誰かがなぜ私を指摘できますか?ありがとうございました!

EDIT:

は2 recvbuffersのための任意の値に当てはめるには、セグメンテーションフォールトし、正しい値を出力しません。このエラーはMPI_Scatter()を使用することに根ざしているようです。

graph->nvtxs = 2; 
    graph->nedges = 4; 
    for(int rank = 0; rank<numProcesses; rank++){ 
     if (rank == myrank){ 
     fprintf(stderr, "%d %d \n",graph->nvtxs, graph->nedges); 
     graph->xadj = malloc((graph->nvtxs + 1) * sizeof(*graph->xadj)); 
     graph->nbrs = malloc(graph->nedges * sizeof(*graph->nbrs)); 
     graph->xadj[graph->nvtxs] = graph->nedges; 

     } 
     MPI_Barrier(MPI_COMM_WORLD); 
    } 
+0

ようこそStackOverflow。 [mcve]を入力してください。それ以外の場合は、デバッグを手助けすることは不可能です。また、状況をデバッグするためにあなた自身の努力をしていると、大きな助けになります。 – Zulan

+0

こんにちは、ありがとう! :)このコードは最小限に抑えることができます。元のソースコードは約500行です。コード内の "..."は、ランク0を使用してファイルを読み込み、2つの配列(サイズnumProcessesのそれぞれ)を埋め込む場所です。したがって、それを含めることは実際には無関係だと感じました。私はこのバグを6時間作業していましたが、ついにこの10行のコードに問題を絞り込むことができました。私は次に何を試してみるか分かりません。私はここに来たのです:/私は2つの配列の値をファイルから読み込まずにプラグインすることでこのエラーを再現しましたが、私はまだ同じ問題があります。 –

答えて

0

問題の解決方法が見つかりました。私はそれを最初に投稿し、それがなぜ機能するのか理解しようとします。

pr_int * nvtxs = malloc(sizeof(pr_int)); 
    pr_int * nedges = malloc(sizeof(pr_int)); 

    MPI_Scatter(verticesCountArray, 1, MPI_INT, &(nvtxs), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 
    MPI_Scatter(edgesCountArray, 1, MPI_INT, &(nedges), 1, MPI_UNSIGNED_LONG, 0, MPI_COMM_WORLD); 

    graph->nvtxs = nvtxs; 
    graph->nedges = nedges; 
    for(int rank = 0; rank<numProcesses; rank++){ 
     if (rank == myrank){ 
     fprintf(stderr, "%d %d \n",graph->nvtxs, graph->nedges); 
     graph->xadj = malloc((graph->nvtxs + 1) * sizeof(*graph->xadj)); 
     graph->nbrs = malloc(graph->nedges * sizeof(*graph->nbrs)); 
     graph->xadj[graph->nvtxs] = graph->nedges; 

     } 
     MPI_Barrier(MPI_COMM_WORLD); 
    } 

私は、普通の変数を受信するための実際のバッファ(ポインタ)を使用していなかったと思います。 mallocの呼び出し中にポインタ(アドレス値)に変換された可能性があります。そのため、構造体のサイズが狂っている可能性があります。しかし、どうして私がなぜ値を印刷できたのか、あるいはランク0が問題なく動作した方法さえも、わかりません。どんなアイデアも大歓迎です!ありがとうございました!

関連する問題