MPI - for Schleife aufteilen
-
Also ich habs jetzt geschafft mein Programm umzuschreiben, es läuft auch daheim auf meinem PC (Hab MPI installiert, danke für den Hinweis!).
Werde das ganze die Tage noch auf dem Cluster in der Uni testen. Freue mich schon, endlich nicht mehr mehrere Stunden auf Ergebnisse warten zu müssen
Vielen Dank nochmal für die Hilfe!
-
kaesekuchen86 schrieb:
Freue mich schon, endlich nicht mehr mehrere Stunden auf Ergebnisse warten zu müssen

Glücklicher, bei mir dauert das trotz MPI+OpenMP immer noch Tage.
-
Hallo, ich bins nochmal....
Ich muss jetzt ein 2 dimenionales Array der Größe n x n aufteilen und scheiter gerad an der Umsetzung. Jeder Prozessor berechnet n/size Reihen des Arrays (size=Anzahl der Prozessoren) und soll sie danach an alle anderen schicken.Ich hab es mit
MPI_Allgather (&array[startgrid][0],n*n/size,MPI_DOUBLE_COMPLEX,&array[startgrid][0],n*n/size,MPI_DOUBLE_COMPLEX,MPI_COMM_WORLD);und mit
MPI_Allgather (&array[startgrid][0],n*n/size,MPI_DOUBLE_COMPLEX,&array[0][0],n*n/size,MPI_DOUBLE_COMPLEX,MPI_COMM_WORLD);und erhalte jedesmal einen Speicherzugriffsfehler. Bei der ersten Methode direkt beim Aufruf von MPI_Allgather, bei der zweiten Methode erst beim Aufruf von MPI_Finalize.
Bei dem Array handelt es sich um einen Vector aus der STL.Was machen ich falsch???
-
Du hast einen vector von vectoren nehme ich an? Denk daran, dass da die Zeilen des Arrays nicht am Stück im Speicher liegen, sondern alle einzeln. Deswegen bekommst du Zugriffsfehler.
-
Zur Not wäre ich auch bereit, das Ganze auf ein eindimensionales Array zu mappen, dieses Array zu senden, und anschließend wieder in ein zweidimensionales Arrays zu verwandeln... Wäre aber eher ne Notlösung.
-
SeppJ schrieb:
Du hast einen vector von vectoren nehme ich an? Denk daran, dass da die Zeilen des Arrays nicht am Stück im Speicher liegen, sondern alle einzeln. Deswegen bekommst du Zugriffsfehler.
Ja hab ich. Hmm, das is blöd, ich bin nicht zwingend auf die Vectorklasse angewiesen. Würde es mit normalen Arrays funktionieren? (Kanns gerad nicht testen, da ich nich zu Hause bin)
-
kaesekuchen86 schrieb:
Würde es mit normalen Arrays funktionieren? (Kanns gerad nicht testen, da ich nich zu Hause bin)
Jein. Es geht hier nicht um vector<->Array. Es geht mit beiden. Entscheidend ist, wie die Daten organisiert sind. Du hast derzeit etwas wie
vector<vector<data> >. Dies entspricht in Array und Pointerschreibweise einemdata**. Da ist alles dynamisch (Anzahl der Zeilen und jeweilige Länge der Zeilen), daher geht beides nicht wenn du es behandelst als würde es hintereinander im Speicher liegen.
Was du brauchst ist eine quasi-eindimensionale Struktur. Wenn die Länge der Zeilen immer gleich ist, ist das kein Problem und du kannst dafür entweder ein Array von Arrays nehmen oder komfortabler einen vector von einer Arrayklasse*. Konkret könnte man dies so machen:template<class T, size_t size> struct Array { T Daten[size]; }; // ... vector<Array<data, N> > array;Wenn deine Zeilen nicht alle gleich lang sind, hast du ein Problem. Dann führt nichts daran vorbei die Zeilen jeweils einzeln zu behandeln.
*: vector von Arrays geht nicht, weil die Vectorklasse eine Kopiersemantik für die Elemente voraussetzt.
-
Danke sehr!
Damit ich dich richtig verstehe:
Bei mir ist die Länge der Zeilen und auch die Länge der Spalten immer gleich. Es reicht also ein ganz normales zweidimensionales Arraycomplex<double> array[n][n]aus?
-
Wäre eine Möglichkeit. Sofern n groß ist, solltest du die Daten auf den Heap packen.
-
Super, habs getestet und funktioniert!
Allerdings würde ich das Array tatsächlich gerne auf dem Heap anlegen, da es sehr groß ist.
Ich kenn mich mit dem new Befehl nicht so aus, sind die Daten dann hintereinander im Speicher?
Wie initialisiert man das Array genau? Bei eindimensionalen Arrays ist es ja einfach.
Kannst du vielleicht ein kleines Mininmalbeispiel posten? Am besten ohne templates usw...(davon hab ich nämlich noch gar keine Ahnung^^)?Vielen Dank jedenfalls für deine Hilfe, du hast mir schon extrem weiter geholfen! (Generell klasse Forum hier)
-
Mit new kannst du keine mehrdimensionalen (im eigentlichen Sinne) Felder erzeugen. Aber die sind ja auch kein Hexenwerk... Nimm ein eindimensionales Feld und lege darin die Zeilen oder Spalten hintereinander, je nach Bedarf. Wenn du dann wirklich ein zweidimensionales brauchst (die Indizes auf 1D umzurechnen finde ich irgendwie angemeher), kannst du zusätzlich noch ein feld von Zeigern erstellen, die dann jeweils auf die entsprechenden Zeilen zeigen... Funktioniert natürlich nur gut, wenn man feste Zeilen- order Spaltenanzahl hat.
-
kaesekuchen86 schrieb:
Danke sehr!
Damit ich dich richtig verstehe:
Bei mir ist die Länge der Zeilen und auch die Länge der Spalten immer gleich. Es reicht also ein ganz normales zweidimensionales Arraycomplex<double> array[n][n]aus?
Ich würde mir dafür einfach eine Wrapper Klasse schreiben, die das ganze sauber verwaltet.
#include <complex> #include <stdexcept> #include <cstdlib> class Matrix { size_t n_,m_; std::complex<double>* field_; public: Matrix (size_t n, size_t m) : n_(n), m_(m) { if ((n_ == 0) || (m_ == 0)) { throw std::logical_error("one dimension is zero"); } field_ = new std::complex<double>[n*m]; } ~Matrix () { delete[] field_; } std::complex<double>& operator()(size_t i,size_t j) { return field_[n_*i+j]; } };Den Rest (CC & Co) kannst Du schnell selbst schreiben.