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).
Ihr lokales Array nicht initialisiert wird. Das könnte den Ärger verursachen. – Mirakurun
Oh danke! Ich habe die Zeile hinzugefügt. Jetzt habe ich noch Probleme mit Segmentierungsfehlern, aber auf anderen Rängen. –
Können Sie mir bitte den Wert der int-Größe mitteilen? Es könnte über 4096 sein und damit das Array überlaufen. – Mirakurun