2017-02-10 4 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). 
-------------------------------------------------------------------------- 

감사 너 너무 많이 녀석들! 여기에 메모리를 할당 전에 배열 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의 다른 할당도 마스터가 아닌 경우에만 조건부로 지정해야합니다.

  • 마찬가지로 주 마스터 섹션 전에 buffer을 할당하지 못했습니다. 이 부분 앞에 할당을 이동하십시오.

  • 근로자 코드를 무조건 실행합니다. 마스터는 작업자 코드를 실행하면 안됩니다.

  • 여기에서 벗어났습니다 for(i = 0; i <= nrows; i++)입니다. i < nrows이어야합니다.

나는 모든 것을 잡았는지 확실하지 않습니다. 또한 할당 할 메모리는 free이어야합니다. 일반적으로 작업 분배 코드는 매우 영리하며 반드시 나쁜 것은 아닙니다. 그러나 균질 시스템에서 정적 작업 부하의 경우 정적 배포가 더 적합합니다. 개별 메시지를 보내는 대신 MPI_ScattervMPI_Gatherv을 사용하는 것이 좋습니다. 이렇게하면 통신 오버 헤드가 줄어 듭니다.

+0

정말 고마워요. 당신이 언급 한 것을 시도해보고 그 결과를 알려 드리겠습니다. – Nick

+0

방금 ​​언급 한 내용이 수정되었습니다. 하지만 여전히 작동하지 않습니다 ... – Nick

+0

내가 언급 한 내용을 수정 한 버전을 추가하는 것이 좋습니다. 원래 버전을 유지하십시오. – Zulan