2017-02-10 5 views
1

私はMPIを使用して簡単な並列プログラミングを行っています。私はコンパイル時にエラーを起こさなかったが、ランタイム中に私が理解できないエラーが発生した。助けてください!君たちありがとう! ソースコードは以下の通りです:Cで並列プログラミング、シグナル:セグメンテーションフォールト:(11)11シグナルコード:アドレス未マッピング(1)

#include <stdio.h> 
#include <stdlib.h> 
#include "mpi.h" 
#include "matrix.h" 
#define MIN(X,Y) (((X) < (Y)) ? (X) : (Y)) //IMPORTANT!! 

int master = 0; 
int numsent, i; 
int nrows, ncols; 
double *A, *x, *b, *buffer; 
int rowidx; 
int sender; 
double ans; 


int main(int argc, char *argv[]) 
{ 
    int myid; 
    int nproc; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &nproc); 
    MPI_Comm_rank(MPI_COMM_WORLD, &myid); 
    /* CODING */ 

    MPI_Status stat; // IMPORTANT!! 

    //master_stage1: master obtain the matrix A and vector X 
    if(myid == master) 
    { 
     printf("What is the number of rows of matrix A:\n"); 
     scanf("%d", &nrows); 
     printf("what is the number of columns of matrix A:\n"); 
     scanf("%d", &ncols); 

     //printf("nrows = %d, ncols = %d\n", nrows, ncols);//text 



     A = (double*)malloc(nrows*ncols*sizeof(double)); 
     b = (double*)malloc(nrows*sizeof(double)); 
     ObtainMatrixAndVector(nrows, ncols, A, x, b); 
    } 

    //master_stage2:bcast x, ncols, nrows, and p2p sent rows of A 
    MPI_Bcast(&ncols, 1, MPI_INT, master, MPI_COMM_WORLD); 
    MPI_Bcast(&nrows, 1, MPI_INT, master, MPI_COMM_WORLD); 

    x = (double*)malloc(ncols*sizeof(double)); 
    MPI_Bcast(x, ncols, MPI_DOUBLE, master, MPI_COMM_WORLD); 

    if(myid == master) 
    { 
     numsent = 0; 
     for(i = 1; i <= MIN(nrows, nproc - 1); i++) 
     { 
      MPI_Send(&A[(i - 1)*ncols], ncols, MPI_DOUBLE, i, i, MPI_COMM_WORLD); 
      numsent++; 
     } 

     //master_stage3: receiving 
     for(i = 0; i <= nrows; i++) 
     { 
      MPI_Recv(&ans, 1, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); 
      sender = stat.MPI_SOURCE; 
      rowidx = stat.MPI_TAG; 
      b[rowidx-1] = ans; 

      if(numsent < nrows) 
      { 
       MPI_Send(&A[numsent*ncols], ncols, MPI_DOUBLE, sender, numsent+1, MPI_COMM_WORLD); 
       numsent++; 
      } 
      else 
       MPI_Send(buffer, ncols, MPI_DOUBLE, sender, 0, MPI_COMM_WORLD); 
     } 
    } 

    //Jobs Done by workers 
    buffer = (double*)malloc(ncols*sizeof(double)); 
    while(1) 
    { 
     if(myid > nrows) 
      break; 
     else 
     { 
      MPI_Recv(buffer, ncols, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); 

      rowidx = stat.MPI_TAG; 
      if(rowidx == 0) 
       break; 
      ans = 0.0; 
      for(i = 0; i < ncols; i++) 
       ans += buffer[i] * x[i]; 
      MPI_Send(&ans, 1, MPI_DOUBLE, master, rowidx, MPI_COMM_WORLD); 

     } 
    } 
    if(myid == master) 
    { 
     for(i = 0; i < nrows; i++) 
      printf("%f\n", b[i]); 
    } 

    /* CODING */ 
    MPI_Finalize(); 
} 

matrix.cファイル:

#include "matrix.h" 

void ObtainMatrixAndVector(int m, int n, double *A, double *x, double *b) 
{ 
// m: number of rows of matrix A 
// n: number of columns of matrix A 
// A: matrix of mxn 
// x: vector of nx1 
// b: vector of mx1 (containing exact solution for comparison purpose) 
// 
    int i, j; 
    for (i = 0; i < m; i++) { 
     x[i] = i + 1; 
     for (j = 0; j < n; j++) { 
      A[i*n+j] = 1.0/(i+j+1); // Hilbert matrix 
     } 
    } 

    // exact solution b = A*x 
    for (i = 0; i < m; i++) { 
     b[i] = 0.0; 
     for (j = 0; j < n; j++) { 
      b[i] += x[j]*A[i*n+j]; 
     } 
    } 
} 

matrix.h:

#ifndef matrix_h 
#define matrix_h 

void ObtainMatrixAndVector(int m, int n, double *A, double *x, double *b); 

#endif /* matrix_h */ 

エラー:

[Nicks-MAC:02138] *** Process received signal *** 
[Nicks-MAC:02138] Signal: Segmentation fault: 11 (11) 
[Nicks-MAC:02138] Signal code: Address not mapped (1) 
[Nicks-MAC:02138] Failing at address: 0x0 
[Nicks-MAC:02138] [ 0] 0 libsystem_platform.dylib   0x00007fffbf27bbba _sigtramp + 26 
[Nicks-MAC:02138] [ 1] 0 a.out        0x0000000106daf0eb x + 4147 
[Nicks-MAC:02138] [ 2] 0 a.out        0x0000000106dad7a1 main + 321 
[Nicks-MAC:02138] [ 3] 0 libdyld.dylib      0x00007fffbf06e255 start + 1 
[Nicks-MAC:02138] *** End of error message *** 
-------------------------------------------------------------------------- 
mpirun noticed that process rank 0 with PID 0 on node Nicks-MAC exited on signal 11 (Segmentation fault: 11). 
-------------------------------------------------------------------------- 

感謝あなたsooooooo多くの人!それにメモリを割り当てる前に、配列のx

 ObtainMatrixAndVector(nrows, ncols, A, x, b); 
} 

//master_stage2:bcast x, ncols, nrows, and p2p sent rows of A 
MPI_Bcast(&ncols, 1, MPI_INT, master, MPI_COMM_WORLD); 
MPI_Bcast(&nrows, 1, MPI_INT, master, MPI_COMM_WORLD); 

x = (double*)malloc(ncols*sizeof(double)); 

あなたポインタを使用して:

+1

質問がCについてのものであれば、なぜC++タグですか?タグをスパムしないでください! –

+0

申し訳ありません。私はちょうど提案のタグをクリックします。私は今C++タグを削除します。 – Nick

答えて

0

は、私はエラーを参照してくださいと思います。

はこれを試してみてください:

A = (double*)malloc(nrows*ncols*sizeof(double)); 
b = (double*)malloc(nrows*sizeof(double)); 
x = (double*)malloc(ncols*sizeof(double)); 
ObtainMatrixAndVector(nrows, ncols, A, x, b); 
+0

あなたの助けてくれてありがとう、アレックス。私はあなたが言ったことを試みたが、それはより多くのエラーを取得します。私はMPIの初心者です。私は今失われています。 – Nick

1

あなたのコードで間違ったものがいくつかあります。

  • あなたがコールObtainMatrixAndVector前にマスターにxを割り当てることができません。それを前にマスタに割り当てます。ただし、xのもう1つの割り当てを、マスター以外の人のみに適用する必要があります。

  • 同様に、メインマスタセクションの前にbufferを割り当てることができません。この部分の前にその割り当てを移動します。

  • ワーカーコードを無条件に実行します。マスターはワーカーコードを実行すべきではありません。

  • ここではオフになっていますfor(i = 0; i <= nrows; i++)i < nrowsである必要があります。

私はすべてをキャッチしたかわかりません。さらに、割り当てるメモリをfreeにする必要があります。一般的に、あなたの作業流通コードは非常に巧妙であり、必ずしも悪いものではありません。しかし、同種のシステム上の静的な作業負荷の場合、静的な配布がより適切です。個々のメッセージを送信する代わりにMPI_ScattervMPI_Gathervを使用することを検討してください。これにより、通信オーバーヘッドが少なくなります。

+0

ありがとうございます。あなたが言及したことを試し、その結果をあなたに知らせます。 – Nick

+0

あなたの言葉を修正しました。しかし、それはまだ動作しません... – Nick

+0

私が言及した内容を修正したバージョンを追加して質問を編集することをお勧めします。しかし、元のバージョンを維持します。 – Zulan

関連する問題