2017-02-10 77 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很多人!

+1

如果問題是關於C,爲什麼C++標記?不要垃圾標籤! –

+0

對不起。我只需點擊建議標籤。我現在將刪除C++標籤。 – Nick

回答

0

我想我看到的錯誤:使用指針

 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)); 

到數組x 內存分配給它。

試試這個:

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

謝謝你幫助Alex。我嘗試了你所說的話,但是卻出現了更多的錯誤。我是MPI的初學者。我現在迷路了。 – Nick

1

有許多事情錯在你的代碼。

  • 你無法通話ObtainMatrixAndVector之前在主分配x。請先在主設備上進行分配。但是,您還必須使其他分配x有條件只有非主人!

  • 類似地,您無法在主要主要部分之前分配buffer。在此部分之前移動該分配。

  • 無條件地執行代碼工作人員。主人不應該執行工人代碼。

  • 你在這裏for(i = 0; i <= nrows; i++),應該是i < nrows

我不確定是否抓住了一切。此外,您還應該分配內存free。一般來說,你的工作分配代碼非常聰明,並不一定是壞的。但是對於同構系統中的靜態工作負載,靜態分配會更合適。考慮使用MPI_ScattervMPI_Gatherv,而不是發送單個消息。這將減少通信開銷。

+0

非常感謝。我會嘗試你提到的並讓你知道結果。 – Nick

+0

我剛剛解決了你提到的問題。但它仍然不起作用... – Nick

+0

我建議你編輯這個問題,添加固定我所提到的版本。儘管保持原始版本。 – Zulan

相關問題