2017-02-07 5 views
-1

Ich habe viele ähnliche Themen hier gesehen, aber das Problem mit mir ist, dass mein Programm tatsächlich für verschiedene Einstellungen läuft.MPI Fehler: (Segmentierungsfehler: 11)

Zum Beispiel: wenn meine Matrix 1024x1024

für 2 Kern: Fehler 11

für 4, 8, 16 usw. funktioniert.

Matrix 2048x2048:

Für Kerneinsetzvorgang: Fehler 11.

Ich verstehe nicht, warum dies geschieht, wird jeder Prozess eine 2048/(Gesamtprozess) X 2028 Matrix nehmen zu berechnen. Und es sollte richtig funktionieren. Diese

ist, wie ich meine Matrix erklären:

int temp[wp][hp]; 

Für erhalten:

rc = MPI_Recv(&temp[0][0], wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status); 

Und senden:

rc = MPI_Send(&temp[0][0], wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD); 

ich es nicht, sollte es sein Arbeiten. Denkst du, es ist vielleicht ein Speicherproblem und nicht pointerbezogen?

+1

C und C++ sind zwei verschiedene Sprachen. Wenn 'wp' und/oder' hp' Variablen sind, ist dies: 'int temp [wp] [hp];' ist nicht zulässig C++. – PaulMcKenzie

+3

Auch, 2048 * 2048 * sizeof (int) '- Betrachten Sie, was das entspricht, und ob Ihr Array lokal oder global deklariert wird. Wenn es lokal ist. Sie können den Stapel ausblasen. – PaulMcKenzie

+1

@PaulMcKenzie Es ist C, Sie haben Recht. Ich bin mir nicht ganz sicher, was Sie global oder lokal meinen. '' temp''Es ist in main() deklariert und für jeden Prozess zugänglich; Diese Matrix sollte 256x2048 sein, wenn wir 8 Prozesse hatten. Die letzte Matrix heißt "im" und es ist 2048x2048, auch für jeden Prozess zugänglich, aber tatsächlich wird nur der Master-Prozess es am Ende verwenden. –

Antwort

2

ich das Array mit malloc schaffen würde

int *temp =(int*)malloc(wp * hp * sizeof(int)); 

dann würde ich die anderen Linien zu

rc = MPI_Recv(temp, wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status); 
mit dem Array

und

rc = MPI_Send(temp, wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD); 

und wenn ich fertig bin ändern Ich gebe es frei.

Wie einer der Kommentatoren bereits erwähnt, ist die Zuweisung der Array auf Ihrem Weg nicht legal C++.

Edit:

, wenn Sie Array zweidimensionaler zugreifen möchten, hier ist das Muster für das:

temp[rowToAccess * numberOfColumns + columnToAcess] 
+0

Danke für die Eingabe! Ich bekomme das jetzt: '' Fehler: subscribted Wert ist kein Array, Zeiger oder Vektor '' '' im [k] [l] = temp [cnt] [l]; '' –

+1

@ MpkRoes Das Problem ist, dass Sie verwenden zweidimensionale Array-Syntax, um auf ein 1-dimensionales "Array" zuzugreifen (es ist eigentlich kein Array, aber nennen wir es aus Gründen des Arguments). Sie müssen also das 2D-Array dynamisch erstellen, wenn Sie die '[] []' - Syntax beibehalten wollen, und hier ist ein gutes 'C'-Buch besser als eine schnelle Antwort auf einer Programmierkarte. – PaulMcKenzie

+1

@MpkRoes - Die Antwort ist grundsätzlich richtig. Das einzige Problem ist, dass Sie 'malloc' verwenden müssen, um ein 2D-Array zu erstellen, so dass Sie die 2D-Array-Syntax' [] [] 'verwenden. Ich habe eine Antwort geschrieben, wenn Sie interessiert sind. – PaulMcKenzie

0

Die Antwort ist im Grunde ein Überblick über das Thema - Sie sind mehr als wahrscheinlich Verwenden des Stapelraums, um das Array zu speichern und somit den für den Stapel reservierten Speicher zu leeren.

Die Lösung besteht also darin, das Array dynamisch zu erstellen.

Hier ist ein Beispiel einen 2D-Array zu schaffen, dynamisch:

#include <stdlib.h> 
//... 
int** create2DArray(unsigned nrows, unsigned ncols) 
{ 
    unsigned i; 
    int** ptr = malloc(nrows * sizeof(int*)); // allocate pointers to rows 
    if (ptr != NULL) 
    { 
     int* pool = malloc(nrows * ncols * sizeof(int)); // allocate pool of memory 
     if (pool != NULL) 
     { 
      for (i = 0; i < nrows; ++i, pool += ncols) 
       ptr[i] = pool; // point the row pointers into the pool 
     } 
     else 
     { 
      free(ptr); 
      ptr = NULL; 
     } 
    } 
    return ptr; 
} 

void delete2DArray(int** arr) 
{ 
    free(arr[0]); // remove the pool 
    free(arr);  // remove the pointers 
} 

int main() 
{ 
    int **temp = create2DArray(2048, 2048); 
    if (temp != NULL) 
    { 
     temp[0][0] = 10; // for example you can use it like a 2D array 
     delete2DArray(temp); // free the memory 
    } 
} 

Diese im Wesentlichen schaffen wird, eine zusammenhängende 2D-Array, ähnlich den Sie int temp[2048][2048] zu erstellen versucht zu verwenden, aber dieses Mal ist der Speicher wird vom Heap, nicht vom Stack erhalten.

Hinweis: Sie können die [][]-Syntax wie ein zweidimensionales Array verwenden.

Ich werde nicht ins Detail gehen, wie es funktioniert, aber es ist einfach genug, um der Logik zu folgen.

+0

Hmmm, wäre es nett C Taktik all meine Arrays so zuzuteilen? –

+0

Wenn Ihre Arrays nicht groß sind und die Dimensionen zur Kompilierzeit bekannt sind, würde ich dies nicht empfehlen, da Sie das Problem haben, dass Sie 'free()' den Speicher machen, sonst bekommen Sie ein Speicherleck. Nur wenn Sie ein Array dynamisch erstellen müssen, sollten Sie dies tun.Die Gründe dafür sind: 1) Die Größe des Arrays ist bis zur Laufzeit unbekannt oder 2) das Array ist zu groß für den Stack. – PaulMcKenzie

+0

Ich habe alle meine Matrizen so gemacht. Es kompiliert. Ich verwende '' send'' und '' recv'' wie in meinem ursprünglichen Beitrag, sonst bekomme ich jede Art von Fehler. Die Berechnungen sind jedoch nicht korrekt. Keine Ahnung, was vor sich geht. –

0

So waren die Probleme:

1) Wie von @PaulMcKenzie und @ Alex angegeben, ich Speicher dynamisch zuteilen musste. Nun war das Problem, dass wenn ich

verwendet
rc = MPI_Send(temp, wp*hp, MPI_INT, 0, tag, MPI_COMM_WORLD); 

oder

rc = MPI_Recv(temp, wp*hp, MPI_INT, i, tag, MPI_COMM_WORLD, &status); 

als @ Alex vorgeschlagen, dann, mein Programm aus irgendeinem Grund abstürzen würde. Also meine ursprüngliche &temp[0][0] war richtig.

2) Das zweite Problem war, dass ich sparte dieses Array Fwrite verwenden, aber wenn u dynamischen Arrays haben, müssen Sie es wie dies zu tun:

for (int i = 0; i < w; i++){ 
for (int j = 0; j < h; j++){ 
    fwrite(&im[i][j], sizeof(int), 1, yourfilename); 
} 
} 

Prost jeder