2016-06-23 4 views
1

habe ich ein Problem mit einem MPI-Code in CSegmentation Fault auf MPI_Gather mit 2D-Arrays

Ich denke, dass ich den guten Algorithmus eine doppelte Schleife mit einer 2D-Array zu verarbeiten erstellt. Aber wenn ich versuche, MPI_Gather zu verwenden, um Daten vom Prozess zu sammeln, gibt es einen Segmentierungsfehlerfehler. Hier ist der Code:

#define NN 4096 
#define NM 4096 

double global[NN][NM]; 

void range(int n1, int n2, int nprocs, int irank, int *ista, int *iend){ 
    int iwork1; 
    int iwork2; 
    iwork1 = (n2 - n1 + 1)/nprocs; 
    iwork2 = ((n2 - n1 + 1) % nprocs); 
    *ista = irank * iwork1 + n1 + fmin(irank, iwork2); 
    *iend = *ista + iwork1 - 1; 
    if (iwork2 > irank) 
     iend = iend + 1; 
} 

void runCalculation(int n, int m, int argc, char** argv) 
{ 
    const int iter_max = 1000; 

    const double tol = 1.0e-6; 
    double error  = 1.0; 

    int rank, size; 
    int start, end; 

    MPI_Init(&argc, &argv); 

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    if (size != 16) MPI_Abort(MPI_COMM_WORLD, 1); 

    memset(global, 0, n * m * sizeof(double)); 

    if(rank == 0){ 
     for (int j = 0; j < n; j++) 
     { 
      global[j][0] = 1.0; 
     } 
    } 

    int iter = 0; 

    while (error > tol && iter < iter_max) 
    { 
     error = 0.0; 

     MPI_Bcast(global, NN*NM, MPI_DOUBLE, 0, MPI_COMM_WORLD); 

     if(iter == 0) 
      range(1, n, size, rank, &start, &end); 

     int size = end - start; 

     double local[size][NM]; 
     memset(local, 0, size * NM * sizeof(double)); 

     for(int j = 1; j < size - 1; j++) 
     { 
      for(int i = 1; i < m - 1; i++) 
      { 
       local[j][i] = 0.25 * (global[j][i+1] + global[j][i-1] 
           + global[j-1][i] + global[j+1][i]); 
       error = fmax(error, fabs(local[j][i] - global[j][i])); 
      } 
     } 

     MPI_Gather(&local[0][0], size*NM, MPI_DOUBLE, &global[0][0], NN*NM, MPI_DOUBLE, 0, MPI_COMM_WORLD); 

     printf("%d\n", iter); 

     if(iter % 100 == 0) 
      printf("%5d, %0.6f\n", iter, error); 

     iter++; 
    } 

    MPI_Finalize(); 

} 

ich dies mit 4096x4096 Arrays laufen. Mit dem Prozessrang 0 wird ein Segmentierungsfehler in der Zeile MPI_Gather erstellt. Ich habe überprüft, ob die Größe für lokale Arrays in Ordnung ist und ich denke, es funktioniert gut.

Bearbeiten: Die Zeile der lokalen Initialisierung hinzugefügt. Neue Zugriffsfehler:

*** Process received signal *** 
Signal: Segmentation fault (11) 
Signal code: Address not mapped (1) 
Failing at address: 0x10602000 
-------------------------------------------------------------------------- 
mpirun noticed that process rank 0 with PID 19216 on machine_name exited on signal 11 (Segmentation fault). 
+0

Ihr lokales Array nicht initialisiert wird. Das könnte den Ärger verursachen. – Mirakurun

+0

Oh danke! Ich habe die Zeile hinzugefügt. Jetzt habe ich noch Probleme mit Segmentierungsfehlern, aber auf anderen Rängen. –

+0

Können Sie mir bitte den Wert der int-Größe mitteilen? Es könnte über 4096 sein und damit das Array überlaufen. – Mirakurun

Antwort

0

Die recvcount Parameter von MPI_Gather die Anzahl der Elemente gibt es von jedem Prozess erhält, nicht die Gesamtzahl der Elemente sie empfängt.

MPI_Gather(&local[0][0], size*NM, MPI_DOUBLE, &global[0][0], NN*NM, MPI_DOUBLE, 0, MPI_COMM_WORLD); 

Sollte sein:

MPI_Gather(&local[0][0], size*NM, MPI_DOUBLE, &global[0][0], size*NM, MPI_DOUBLE, 0, MPI_COMM_WORLD); 
+0

Und ... es funktioniert! Netter Fangmann, danke! –