Ich entwickle derzeit eine Domänenzerlegungsmethode zur Lösung des Streuproblems. Grundsätzlich löse ich iterativ ein System von Helmholtz-BVPs. Ich diskretisiere die Gleichungen mit der Finite-Elemente-Methode über Dreiecks- oder Tetraedernetzen. Ich entwickle den Code für meine Doktorarbeit. Ich kenne einige der vorhandenen Finite-Elemente-Bibliotheken wie deal.ii oder DUNE und obwohl ich denke, dass sie mit inspirierendem Design und API für Lernzwecke großartig sind, wollte ich meine eigene kleine Anwendung von Grund auf neu entwickeln.
Ich bin an einem Punkt angelangt, an dem meine seriellen Versionen ausgeführt werden, und jetzt möchte ich sie parallelisieren. Schließlich ist es eine der Stärken des Domänenzerlegungs-Frameworks, Algorithmen zu formulieren, die zumindest im Prinzip leicht zu parallelisieren sind. In der Praxis gibt es jedoch viele Details, die berücksichtigt werden müssen. Mesh Management ist einer von ihnen. Wenn die Anwendungen eine hohe Auflösung erreichen und gleichzeitig auf viele CPUs skaliert werden sollen, ist die Replikation eines gesamten Netzes auf jeder CPU ineffizient.
Ich wollte die Entwickler, die an ähnlichen Anwendungen in Hochleistungsrechnerumgebungen arbeiten, fragen, wie sie mit diesem Problem umgehen.
Es gibt eine p4est-Bibliothek für die verteilte Netzverwaltung. Ich brauche AMR nicht, daher könnte es ein Overkill sein, da ich nur an der Verwendung einheitlicher Netze interessiert bin und nicht sicher bin, ob es Dreiecksnetze verfeinern kann. Ich könnte auch einfach ein einheitliches Netz erstellen und es dann in einen der Netzpartitionierer einspeisen und die Ausgabe nachbearbeiten.
Der einfachste Ansatz scheint darin zu bestehen, für jede Partition eine separate Datei zu erstellen, die Netzinformationen enthält, die nur für diese bestimmte Partition relevant sind. Diese Datei würde von einer einzelnen CPU gelesen, die für die Montage des diskreten Systems auf diesem Teil des Netzes verantwortlich wäre. Natürlich müssten einige globale Partitionskonnektivitäts- / Nachbarschaftsinformationen auch in einer Datei gespeichert werden, die von allen CPUs für die Kommunikation zwischen Prozessen gelesen wird.
Welche anderen Ansätze gibt es da draußen? Wenn einige von Ihnen dies mitteilen könnten, welche Methoden werden in der Branche oder bei staatlichen Forschungseinrichtungen im Zusammenhang mit der Behandlung dieses Problems häufig verwendet? Ich bin ziemlich neu in der Programmierung eines parallelen Finite-Elemente-Lösers und wollte ein Gefühl dafür bekommen, ob ich über dieses Problem richtig nachdenke oder nicht und wie andere es angehen. Jeder Rat oder Hinweis auf relevante Forschungsartikel wäre sehr dankbar!
Danke im Voraus!
Antworten:
Wenn Sie AMR nicht verwenden und nicht über 1K-4K-Kerne hinaus skalieren möchten, tun Sie dies einfach.
Rang 0 liest das gesamte Netz und partitioniert es mit METIS / Scotch usw. (Hinweis: Dies ist eine serielle Operation).
Rang 0 sendet die Element- / Knotenpartitionierungsinformationen an alle anderen Ränge und gibt den Speicher frei (der zum Speichern des Netzes verwendet wird).
Alle Ränge lesen die Knoten / Elemente, die sie besitzen (einschließlich Geisterknoten), aus derselben Eingabedatei (Hinweis: 2000 Ränge, die auf dieselbe Eingabedatei zugreifen, klingen möglicherweise langsam, sind aber in der Praxis nicht sinnvoll, obwohl dies für das Dateisystem möglicherweise schlecht ist, aber dann für uns mache es nur einmal).
Alle Ränge müssen die lokalen zu globalen Knoten- / Element- / Dof-Zuordnungen für die Anwendung von BCs und das Zusammenstellen von Matrizen erstellen und die Knoten neu nummerieren.
Nachdem alles gesagt und getan ist, sind alle Daten in einem Rang lokal, sodass Sie in der Lage sein sollten, gut zu skalieren (in Bezug auf den Speicher). Ich mache das alles in ungefähr 100 Zeilen (siehe Zeilen 35-132 hier ) in einem kleinen Code von mir.
Wenn Ihr Netz zu groß ist (z. B.> 100-250 Millionen Elemente), als dass Sie es nicht mit METIS auf einem einzelnen Knoten partitionieren können und ParMETIS / PT-Scotch benötigen, müssen Sie es zusätzlich vor allen Kernen parallel partitionieren. Reihen können es lesen. In einem solchen Szenario ist es aus logistischen Gründen möglicherweise einfacher, die Partitionierungsphase vom Hauptcode zu trennen.
Übrigens machen AMR-Bibliotheken normalerweise keine Tet. Auch PETSc ist eine gute Wahl für die Parallelisierung Ihres Codes.
Edit: Siehe auch hier und hier .
quelle
Dies mag Sie nicht überraschen, da ich einen Deal entwickle. II, aber hier ist meine Perspektive: Wenn ich mit Studenten spreche, fordere ich sie normalerweise auf, am Anfang ihren eigenen Prototyp zu entwickeln, damit sie sehen können, wie es gemacht wird. Aber sobald sie etwas Kleines zum Laufen gebracht haben, lasse ich sie eine Bibliothek verwenden, die es ihnen ermöglicht, so viel weiter zu gehen, weil sie das Rad nicht bei jedem Schritt neu erfinden müssen.
In Ihrem Fall haben Sie bereits gesehen, wie Sie einen einfachen Helmholtz-Löser implementieren. Aber Sie werden die nächsten 6 Monate damit verbringen, den dafür erforderlichen Code parallel zu schreiben. Sie werden weitere 3 Monate damit verbringen, kompliziertere Geometrien zu verwenden. Sie verbringen dann weitere 6 Monate, wenn Sie einen effizienten Löser wünschen. Und die ganze Zeit schreiben Sie Code, der bereits von jemand anderem geschrieben wurde und der Sie in gewisser Weise nicht näher an das bringt, was Sie tatsächlich für Ihre Promotion tun müssen: etwas Neues entwickeln, das es noch nicht gab vorher gemacht. Wenn Sie diesen Weg gehen, verbringen Sie 2-3 Jahre Ihrer Doktorarbeit damit, das zu wiederholen, was andere getan haben, und vielleicht 1 Jahr damit, etwas Neues zu tun.
Die Alternative ist, dass Sie jetzt 6 Monate damit verbringen, eine der vorhandenen Bibliotheken zu lernen, aber danach haben Sie 2-3 Jahre Zeit, in denen Sie wirklich neue Dinge tun, Dinge, in denen Sie jede zweite Woche in das Büro Ihres Beraters gehen und ihn / sie zeigen können Sie ist etwas wirklich Neues, das in großem Maßstab läuft oder in anderer Hinsicht einfach sehr cool ist. Ich denke, Sie sehen wahrscheinlich, wohin ich jetzt damit gehe.
quelle
Dies ist keine vollständige Antwort.
Bei der Implementierung paralleler Domänenzerlegungsmethoden sind einige Komplikationen aufgetreten. Erstens kann man viele Prozessoren für eine Subdomäne verwenden oder einen Prozessor mit vielen Subdomänen versorgen, und man möchte möglicherweise beide Paradigmen implementieren. Zweitens erfordert die substrukturierte Form von Domänenzerlegungsmethoden das Trennen der Flächen, Kanten und Scheitelpunkte von Unterdomänen (nicht von Elementen). Ich glaube nicht, dass diese Komplikationen leicht in das parallele Netzmanagement einbezogen werden können. Die Situation wird einfacher, wenn Sie einen Prozessor für eine Subdomain betrachten und die überlappende RAS / RASHO-Methode verwenden. Selbst in diesem Fall sollten Sie Ihr paralleles Layout besser selbst verwalten.
quelle