Умножение матрицы MPI с динамическим распределением: Seg.придираться - PullRequest
2 голосов
/ 29 июля 2011

Я делаю программу умножения матриц в OpenMPI, и я получил это сообщение об ошибке:

[Mecha Liberta:12337] *** Process received signal ***
[Mecha Liberta:12337] Signal: Segmentation fault (11)
[Mecha Liberta:12337] Signal code: Address not mapped (1)
[Mecha Liberta:12337] Failing at address: 0xbfe4f000
--------------------------------------------------------------------------
mpirun noticed that process rank 1 with PID 12337 on node Mecha Liberta exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

Вот как я определяю матрицы:

  int **a, **b, **r;

  a = (int **)calloc(l,sizeof(int));

  b = (int **)calloc(l,sizeof(int));

  r = (int **)calloc(l,sizeof(int));

  for (i = 0; i < l; i++)
      a[i] = (int *)calloc(c,sizeof(int));

  for (i = 0; i < l; i++)
      b[i] = (int *)calloc(c,sizeof(int));      

   for (i = 0; i < l; i++)
      r[i] = (int *)calloc(c,sizeof(int)); 

А вот мой Send / Recv (я уверен, что моя проблема должна быть здесь):

  MPI_Send(&sent, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); 
  MPI_Send(&lines, 1, MPI_INT, dest, tag, MPI_COMM_WORLD);   
  MPI_Send(&(a[sent][0]), lines*NCA, MPI_INT, dest, tag, MPI_COMM_WORLD); 
  MPI_Send(&b, NCA*NCB, MPI_INT, dest, tag, MPI_COMM_WORLD);

и

MPI_Recv(&sent, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);  
MPI_Recv(&lines, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
MPI_Recv(&a, lines*NCA, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
MPI_Recv(&b, NCA*NCB, MPI_INT, 0, tag, MPI_COMM_WORLD, &status); 

Кто-нибудь может увидеть, в чем проблема?

1 Ответ

3 голосов
/ 29 июля 2011

Это распространенная проблема с C и многомерными массивами и MPI.

В этой строке произнесите:

MPI_Send(&b, NCA*NCB, MPI_INT, dest, tag, MPI_COMM_WORLD);

вы говорите MPI отправлять целые числа NCAxNCB, начиная с b до dest,MPI_COMM_WORLD с тегом tag. Но , b не указатель на целые числа NCAxNCB; это указатель на указатели NCA на целые числа NCB.

Итак, вы хотите убедиться, что ваши массивы непрерывны (возможно, в любом случае лучше для производительности), используя что-то вроде этого:

int **alloc_2d_int(int rows, int cols) {
    int *data = (int *)malloc(rows*cols*sizeof(int));
    int **array= (int **)malloc(rows*sizeof(int*));
    for (int i=0; i<rows; i++)
        array[i] = &(data[cols*i]);

    return array;
}

  /* .... */

  int **a, **b, **r;

  a = alloc_2d_int(l, c);
  b = alloc_2d_int(l, c);
  r = alloc_2d_int(l, c);

, а затем

  MPI_Send(&sent, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); 
  MPI_Send(&lines, 1, MPI_INT, dest, tag, MPI_COMM_WORLD);  
  MPI_Send(&(a[sent][0]), lines*NCA, MPI_INT, dest, tag, MPI_COMM_WORLD); 
  MPI_Send(&(b[0][0]), NCA*NCB, MPI_INT, dest, tag, MPI_COMM_WORLD);

MPI_Recv(&sent, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);  
MPI_Recv(&lines, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
MPI_Recv(&(a[0][0]), lines*NCA, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
MPI_Recv(&(b[0][0]), NCA*NCB, MPI_INT, 0, tag, MPI_COMM_WORLD, &status); 

должен работать больше, чем ожидалось.

...