2017-02-10 24 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)); 

Вы с помощью указатель на массив х перед тем выделения памяти для него.

Попробуйте это:

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

Есть целый ряд вещей неправильно в вашем коде.

  • Вы не выделить x на мастер перед вызовом ObtainMatrixAndVector. Выделите это раньше на хозяине. Однако вы также должны сделать другое распределение x условным только для не-мастеров!

  • Аналогичным образом вы не можете выделить buffer перед основной основной секцией. Переместите выделение перед этой частью.

  • Вы производите рабочий код безоговорочно. Мастер не должен выполнять рабочий код.

  • Вы здесь for(i = 0; i <= nrows; i++), должно быть i < nrows.

Я не уверен, поймал ли я все. Далее вы также должны указать free память, которую вы выделяете. В общем, ваш код распределения работы довольно умный и не обязательно плохой. Но для статических нагрузок на однородных системах более подходящим было бы статическое распределение. Рассмотрите возможность использования MPI_Scatterv и MPI_Gatherv вместо отправки отдельных сообщений. Это будет меньше затрат на связь.

+0

Большое вам спасибо. Я попробую то, что вы упомянули, и дайте знать результат. – Nick

+0

Я только что исправил то, что вы упомянули. Но он все еще не работает ... – Nick

+0

Предлагаю вам отредактировать вопрос, добавив версию, в которой вы исправили то, что я упомянул. Однако сохраните исходную версию. – Zulan