MPI-I/O: buffer macht Probleme

mag1000

Grünschnabel
Hallo,

Die MPI-Routinen eines vorhandenen Programmes will ich verbessern.
Dabei soll der Buffer, der vorher fest angegeben wurde, nun dynamisch sein:

Das ist der alte I/O-Code, der funktioniert:

C:
double dummyArray[64][64];
pnt_config->MPI_MyOffset = 0;
MPI_File_set_view(pnt_config->MPI_MyFile, pnt_config->MPI_MyOffset, pnt_config->MPI_MyDatatype, pnt_config->MPI_MySubArray, "native", MPI_INFO_NULL);
MPI_File_read_all(pnt_config->MPI_MyFile,&dummyArray,pnt_config->MPI_intArray_Subsize[0]*pnt_config->MPI_intArray_Subsize[1],pnt_config->MPI_MyDatatype,&pnt_config->MPI_MyStatus);
for (k=pnt_config->int_kStartReal; k <= pnt_config->int_kEndReal; k++)
{
                for (j=pnt_config->int_jStartReal; j <= pnt_config->int_jEndReal; j++)
                {
                               for (i=pnt_config->int_iStartReal; i <= pnt_config->int_iEndReal; i++)
                               {
                                               pnt_mesh->x[i][j][k]=dummyArray[i-(pnt_config->int_iStartReal)][j-(pnt_config->int_jStartReal)];
                               }
                }
}
Der Nachteil des Codes bestelt nun darin, dass man wissen muss, dass die Datei 64*64 Werte einzulesen hat.
Also wollte ich das anpassen mit dynamischer Speicherverwaltung:

C:
double ** dummyArray;
dummyArray = (double **)malloc(int_iMeshPoints * sizeof(double *));
for (i=0; i < int_iMeshPoints; i++)
{
                dummyArray[i] = (double *)malloc(int_jMeshPoints * sizeof(double));
}
pnt_config->MPI_MyOffset = 0;
MPI_File_set_view(pnt_config->MPI_MyFile, pnt_config->MPI_MyOffset, pnt_config->MPI_MyDatatype, pnt_config->MPI_MySubArray, "native", MPI_INFO_NULL);
MPI_File_read_all(pnt_config->MPI_MyFile,dummyArray,pnt_config->MPI_intArray_Subsize[0]*pnt_config->MPI_intArray_Subsize[1],pnt_config->MPI_MyDatatype,&pnt_config->MPI_MyStatus);
for (k=pnt_config->int_kStartReal; k <= pnt_config->int_kEndReal; k++)
{
                for (j=pnt_config->int_jStartReal; j <= pnt_config->int_jEndReal; j++)
                {
                               for (i=pnt_config->int_iStartReal; i <= pnt_config->int_iEndReal; i++)
                               {
                                               pnt_mesh->x[i][j][k]=dummyArray[i-(pnt_config->int_iStartReal)][j-(pnt_config->int_jStartReal)];
                               }
                }
}
Der neue Code funktioniert nicht.
Jemand eine Idee?

Gruß
mag
 
Zuletzt bearbeitet:
Hi

Wenn du genau sagst, was nicht funktioniert, könnte man schneller/gezielter helfen.
Compilerfehler? Absturz des Programms (mit Fehlermeldung)? Aufhängen? ...?
 
Natürlich, Entschuldigung!
Also das Programm stürzt ab und folgender Fehler wird ausgegeben:

C:
[pc60:27832] *** Process received signal ***

[pc60:27832] Signal: Segmentation fault (11)

[pc60:27832] Signal code:  (128)

[pc60:27832] Failing at address: (nil)

[pc60:27832] [ 0] /lib64/libpthread.so.0(+0xf2e0) [0x7f9fb3ce82e0]

[pc60:27832] [ 1] /work/eclipse/saiWENOS/Debug/saiWENOS(MeshImport+0x237) [0x41aa6b]

[pc60:27832] [ 2] /work/eclipse/saiWENOS/Debug/saiWENOS(main+0x20a) [0x41cbca]

[pc60:27832] [ 3] /lib64/libc.so.6(__libc_start_main+0xfd) [0x7f9fb3997b7d]

[pc60:27832] [ 4] /work/eclipse/saiWENOS/Debug/saiWENOS() [0x402239]

[pc60:27832] *** End of error message ***

--------------------------------------------------------------------------

mpirun noticed that process rank 2 with PID 27832 on node pc60 exited on signal 11 (Segmentation fault).

--------------------------------------------------------------------------

für die anderen MPI-Prozesse erhalte ich die gleichen Fehler.
 
C++:
array[x][y]
wird zu
C++:
array[x*int_jMeshPoints + y]

Das Problem am Ganzen war, das du zuerst kein zweidim. Array gemacht hast, sondern ein Pointerarray, bei dem jeder Pointer wieder auf ein Array zeigt.
Das ist ein Unterschied.

Und ein zweidim. Array, bei dem "Länge" und "Breite" beide variabel sind...
ist so, mit dem "Umweg" über eindim., am einfachsten.

Gruß

PS: free nicht vergessen!
 
Zuletzt bearbeitet:
Cool,
damit funktioniert es tatsächlich =).
Damit kann ich dann auch die MPI-SendRec Befehle realisieren.
Die MPI-Kommunikation wird bei mir sehr oft durchgeführt. Kennst du dich etwas mit Performance aus und könntest mir sagen, ob es schneller ist, wenn ich einmal eine Buffer anlege, den ich immer wieder verwende, oder ob ich auch vor jedem MPI-SendRec den Buffer neu anlegen und dann wieder freigeben kann? Das wäre nämlich deutlich schneller umzusetzen.

Gruß
 
Ändert sich die Größe des Buffers jedesmal?

Wenn nicht: Wiederverwenden ist auf jeden Fall besser für die Geschwindigkeit. Nicht immer neu anlegen.

Wenn schon: Nur dann einen neuen anlegen (und den alten weg), wenn der Alte zu klein ist.
Solange nur gleich viel oder weniger Größe gebraucht wird, den aktuellen weiterverwenden.

Gruß
 
Zurück