MPI_B sendet ein dynamisches 2d-Array

8

Ich versuche ein dynamisches 2d-Array mit bcast an alle Ränge zu übergeben. Ich habe den folgenden Code.

%Vor%

Aus irgendeinem Grund kann ich nicht verstehen, dass ich einen Segmentierungsfehler bekomme. Wer weiß, wo das Problem ist?

    
faulpin 24.02.2011, 12:45
quelle

5 Antworten

6

Das array sollte 100 statt 10 sein, da Sie 10 Floats pro Zeile zuweisen. JackNs Antwort hat den Code dafür.

Bei jedem anderen Prozess als Rang 0 ist der Zeiger auf das Array jedoch null . Sie müssen das Array für alle Prozesse initialisieren und anschließend das Array im Root-Verzeichnis füllen.

Sie können den Malloc-Code einfach aus dem if (rank ==0) -Block entfernen und er sollte wie erwartet funktionieren.

    
davidb 24.02.2011, 13:00
quelle
22

Hier gibt es drei Punkte - einer mit Zuweisungen, einer mit Zuordnung und einer mit der Funktionsweise von MPI, und keine der anderen Antworten berührt sie alle.

Das erste und wichtigste Problem ist, wo Dinge zugeteilt werden. Wie von @davidb richtig ausgeführt, reserviert man Speicher nur für Task Null, so dass die anderen Tasks keinen Speicher haben, in dem die Übertragung empfangen werden kann.

Wie für 2d Allokationen in C im Allgemeinen ist Ihr Code fast genau richtig. In diesem Codeblock:

%Vor%

Das einzige wirkliche Problem ist, dass das erste malloc aus 10 float Zeigern bestehen sollte, nicht aus Floaten:

%Vor%

Darauf hat @eznme hingewiesen. Der erste Weg funktioniert möglicherweise abhängig von dem Speichermodell, mit dem Sie kompilieren / verlinken usw. und wird mit hoher Wahrscheinlichkeit auf 32-Bit-Betriebssystemen / -Maschinen funktionieren - aber nur weil es funktioniert, bedeutet es nicht immer, dass es richtig ist:)

Nun, das letzte Problem ist, dass Sie ein perfektes 2d-Array in C deklariert haben, aber das ist nicht das, was MPI erwartet. Wenn Sie diesen Anruf tätigen,

%Vor%

Sie sagen MPI, dass sie 100 zusammenhängende Floats senden soll, auf die von array gezeigt wird. Sie bemerken, dass die Bibliotheksroutine nicht wissen kann, ob Array der Zeiger auf den Anfang eines 2D- oder 3D- oder 12D-Arrays ist oder wie die einzelnen Dimensionen sind; es weiß nicht, ob es den Zeigern folgen muss, und wenn es so wäre, wüsste es nicht, wie viele es folgen sollen.

Sie möchten also einen Float-Zeiger an 100 zusammenhängende Floats senden - und in der normalen C-Weise zum Zuweisen von pseudo-multidimensionalen Arrays (*) müssen Sie das nicht unbedingt haben. Sie wissen nicht unbedingt, wie weit die 2. Reihe von der 1. Reihe in diesem Layout entfernt ist - oder auch in welche Richtung. Was Sie also wirklich tun möchten, ist etwa so:

%Vor%

Auf diese Weise und nur auf diese Weise ist garantiert, dass der Speicher zusammenhängend ist. Dann können Sie

tun %Vor%

Beachten Sie, dass Sie für eine beliebige Anordnung von Daten immer noch Bcast verwenden könnten, indem Sie einen MPI-Datentyp definieren, der beschreibt, wie das 2d-Array tatsächlich im Speicher angeordnet ist; aber das ist einfacher und näher an dem, was Sie wahrscheinlich wirklich wollen.

(*) Das wirkliche Problem hier ist, dass C- und C-abgeleitete Sprachen keine echten Multi-D-Arrays als erstklassige Objekte haben - was für eine Systemprogrammiersprache gut ist, aber bei der wissenschaftlichen Programmierung irritierend ist.

    
Jonathan Dursi 24.02.2011 16:29
quelle
2
___ qstntxt ___

Ich versuche ein dynamisches 2d-Array mit bcast an alle Ränge zu übergeben. Ich habe den folgenden Code.

%Vor%

Aus irgendeinem Grund kann ich nicht verstehen, dass ich einen Segmentierungsfehler bekomme. Wer weiß, wo das Problem ist?

    
___ answer5104998 ___

Wahrscheinlich möchten Sie das erste malloc in

ändern %Vor%

, weil das Array Zeiger speichert und Gleitkommazahlen anstelle von Eingängen speichert:

%Vor%     
___ qstnhdr ___ MPI_B sendet ein dynamisches 2d-Array ___ answer16491498 ___

Wenn Sie ein Array mit 10 * 10 belegen möchten, geben Sie Ihren Code ein:

%Vor%

sollte

sein %Vor%     
___ tag123mpi ___ MPI ist die Message Passing-Schnittstelle, eine Bibliothek für die parallele Programmierung verteilter Speicher und die De-facto-Standardmethode für die Verwendung verteilter Speichercluster für technisches Hochleistungsrechnen. Fragen zur Verwendung von MPI für die parallele Programmierung gehen unter diesem Tag; Fragen zu zB Installationsproblemen bei MPI-Implementierungen werden am besten mit dem entsprechenden implementierungsspezifischen Tag, zB MPICH oder OpenMPI, versehen. ___ tag123c ___ C ist eine universelle Computerprogrammiersprache, die für Betriebssysteme, Bibliotheken, Spiele und andere Hochleistungsanwendungen verwendet wird. Dieses Tag sollte bei allgemeinen Fragen zur C-Sprache verwendet werden, wie in der Norm ISO 9899: 2011 definiert. Fügen Sie ggf. ein versionsspezifisches Tag wie c99 oder c90 für Fragen zu älteren Sprachstandards hinzu. C unterscheidet sich von C ++ und es sollte nicht mit dem C ++ - Tag kombiniert werden, wenn ein rationaler Grund fehlt. ___ answer5107489 ___

Hier gibt es drei Punkte - einer mit Zuweisungen, einer mit Zuordnung und einer mit der Funktionsweise von MPI, und keine der anderen Antworten berührt sie alle.

Das erste und wichtigste Problem ist, wo Dinge zugeteilt werden. Wie von @davidb richtig ausgeführt, reserviert man Speicher nur für Task Null, so dass die anderen Tasks keinen Speicher haben, in dem die Übertragung empfangen werden kann.

Wie für 2d Allokationen in C im Allgemeinen ist Ihr Code fast genau richtig. In diesem Codeblock:

%Vor%

Das einzige wirkliche Problem ist, dass das erste malloc aus 10 float Zeigern bestehen sollte, nicht aus Floaten:

%Vor%

Darauf hat @eznme hingewiesen. Der erste Weg funktioniert möglicherweise abhängig von dem Speichermodell, mit dem Sie kompilieren / verlinken usw. und wird mit hoher Wahrscheinlichkeit auf 32-Bit-Betriebssystemen / -Maschinen funktionieren - aber nur weil es funktioniert, bedeutet es nicht immer, dass es richtig ist:)

Nun, das letzte Problem ist, dass Sie ein perfektes 2d-Array in C deklariert haben, aber das ist nicht das, was MPI erwartet. Wenn Sie diesen Anruf tätigen,

%Vor%

Sie sagen MPI, dass sie 100 zusammenhängende Floats senden soll, auf die von %code% gezeigt wird. Sie bemerken, dass die Bibliotheksroutine nicht wissen kann, ob Array der Zeiger auf den Anfang eines 2D- oder 3D- oder 12D-Arrays ist oder wie die einzelnen Dimensionen sind; es weiß nicht, ob es den Zeigern folgen muss, und wenn es so wäre, wüsste es nicht, wie viele es folgen sollen.

Sie möchten also einen Float-Zeiger an 100 zusammenhängende Floats senden - und in der normalen C-Weise zum Zuweisen von pseudo-multidimensionalen Arrays (*) müssen Sie das nicht unbedingt haben. Sie wissen nicht unbedingt, wie weit die 2. Reihe von der 1. Reihe in diesem Layout entfernt ist - oder auch in welche Richtung. Was Sie also wirklich tun möchten, ist etwa so:

%Vor%

Auf diese Weise und nur auf diese Weise ist garantiert, dass der Speicher zusammenhängend ist. Dann können Sie

tun %Vor%

Beachten Sie, dass Sie für eine beliebige Anordnung von Daten immer noch %code% verwenden könnten, indem Sie einen MPI-Datentyp definieren, der beschreibt, wie das 2d-Array tatsächlich im Speicher angeordnet ist; aber das ist einfacher und näher an dem, was Sie wahrscheinlich wirklich wollen.

(*) Das wirkliche Problem hier ist, dass C- und C-abgeleitete Sprachen keine echten Multi-D-Arrays als erstklassige Objekte haben - was für eine Systemprogrammiersprache gut ist, aber bei der wissenschaftlichen Programmierung irritierend ist.

    
___ answer5104999 ___

Das %code% sollte 100 statt 10 sein, da Sie 10 Floats pro Zeile zuweisen. JackNs Antwort hat den Code dafür.

Bei jedem anderen Prozess als Rang 0 ist der Zeiger auf das Array jedoch %code% . Sie müssen das Array für alle Prozesse initialisieren und anschließend das Array im Root-Verzeichnis füllen.

Sie können den Malloc-Code einfach aus dem %code% -Block entfernen und er sollte wie erwartet funktionieren.

    
___
jacknad 24.02.2011 12:51
quelle
1

Wahrscheinlich möchten Sie das erste malloc in

ändern %Vor%

, weil das Array Zeiger speichert und Gleitkommazahlen anstelle von Eingängen speichert:

%Vor%     
Bernd Elkemann 24.02.2011 12:59
quelle
0

Wenn Sie ein Array mit 10 * 10 belegen möchten, geben Sie Ihren Code ein:

%Vor%

sollte

sein %Vor%     
Mark Z. 10.05.2013 22:11
quelle

Tags und Links