Was ist eine gute Möglichkeit, Parameterstudien in C ++ durchzuführen?

29

Das Problem

Ich arbeite derzeit an einer Finite-Elemente-Navier-Stokes-Simulation und möchte die Auswirkungen einer Vielzahl von Parametern untersuchen. Einige Parameter werden in einer Eingabedatei oder über eine Befehlszeile angegeben. Andere Parameter werden als Flags in einem Makefile bereitgestellt, sodass mein Code immer dann neu kompiliert werden muss, wenn ich diese Optionen ändere. Mich würde interessieren, wie man den Parameterraum systematisch erforschen kann.

  • Gibt es nützliche C ++ / Python-Bibliotheken / Frameworks, die Ihnen dabei helfen können? Zum Beispiel war das Erkennen von boost.Program_options eine große Hilfe, da es möglich ist, Eingabedateioptionen mit Befehlszeilenargumenten zu überladen. Ich habe auch gesehen, dass einige Leute eine Jobdatei verwenden, die jeden Fall ziemlich effektiv beschreibt, und ein Kollege schlug vor, dass das Schreiben von Parametern in vtu-Dateien als Kommentarblöcke auch funktionieren könnte.
  • Vielleicht lohnt es sich gar nicht, viel Zeit dafür zu investieren? Ist es nur eine Ablenkung und eine Zeitverschwendung und es ist am besten, nur Muskeln durch den Testprozess zu ziehen, und zwar brachial und ad hoc?

Einige Gedanken

Ich mache die Dinge derzeit meistens von Hand und habe die folgenden Probleme festgestellt:

  • Testfälle benennen . Ich habe versucht, die Ergebnisse in Ordnern zu speichern, deren Laufparameter durch Unterstriche voneinander getrennt sind, z Re100_dt02_BDF1.... Diese werden schnell lang oder schwer lesbar / kryptisch, wenn sie zu stark abgekürzt werden. Zu den reellen Zahlenparametern gehört auch ein, .was umständlich / hässlich ist.
  • Laufdaten protokollieren . Manchmal möchte ich sehen, dass die Ergebnisse in das Terminal geschrieben und auch in einer Textdatei gespeichert werden. Diese Antwort von StackOverflow ist zum Beispiel etwas hilfreich, aber die Lösungen scheinen ein bisschen aufdringlich zu sein.
  • Zeichnen von Daten gemäß Parameter . Es dauert einige Zeit, relevante Daten aus einer Vielzahl von Protokolldateien in einer einzigen Datei zu sammeln, die ich dann plotten kann. Mit einem besseren System würde dies möglicherweise einfacher.
  • Aufzeichnung von Kommentaren zu den Daten . Nach der Überprüfung der Ergebnisse schreibe ich einige Kommentare in eine Textdatei, aber es ist manchmal schwierig, diese mit den Ergebnisordnern zu synchronisieren.
Matija Kecman
quelle
Viel hängt davon ab, was Sie mit "erkunden" meinen. Bitte geben Sie Ihre Ziele genauer an.
Arnold Neumaier

Antworten:

10

Nur ein paar Kommentare zu zwei Ihrer Punkte:

  • Laufdaten protokollieren : Ihre beste Wette ist wahrscheinlich die Weiterleitung der Ausgabe über den Befehl tee , der in den meisten Shells verfügbar sein sollte.

  • Zeichnen von Daten nach Parametern : Ich denke, es ist Geschmackssache, aber wenn ich komplexe Datenaggregationen durchführen muss, speichere ich die Ergebnisse im Klartext, lese sie in Matlab als Matrizen ein und führe alle Berechnungen, das Zeichnen und sogar die LaTeX-Ausgabe durch von dort. Unabhängig davon, mit welcher Programmier- / Skriptsprache Sie vertraut sind, erzielen Sie natürlich die besten Ergebnisse.

Pedro
quelle
Danke, der teeBefehl ist sehr nützlich
Matija Kecman
11

Wenn Sie etwas für allgemeine Zwecke schreiben möchten, können Sie dies entweder mit Shell-Skripten tun, wenn es sehr einfach ist, wie Pedro vorschlägt , oder in einer höheren mathematischen Programmiersprache wie Python oder MATLAB aggregieren. Ich bin damit einverstanden, dass reine Textdateien für kleinere Datenmengen nützlich sind, aber Sie sollten wahrscheinlich für alles, was größer als ein paar Megabyte ist, auf Binärdaten umsteigen.

Auf der anderen Seite würde ich, wenn Sie nur eine Parameterschätzung durchführen, die Verwendung einer speziell dafür geeigneten Software empfehlen. Mehrere Forscher an meiner Universität hatten viel Glück mit DAKOTA , einer Toolbox zur Quantifizierung von Unsicherheiten der Sandia National Laboratories ( verfügbar unter einer GNU Lesser General Public License ).

Hier ist ein Auszug aus der Sandia-Seite, die DAKOTA beschreibt:

Wir bieten eine Vielzahl von Methoden, mit denen ein Benutzer eine Sammlung von Computersimulationen ausführen kann, um die Empfindlichkeit der Modellausgaben in Bezug auf Modelleingaben zu bewerten. Häufige Kategorien sind Parameterstudien, Stichprobenverfahren und Versuchsplanung. In Parameterstudien werden einige Eingabeparameter in einem Bereich schrittweise durchlaufen, während andere Eingabeparameter festgehalten werden, und es wird bewertet, wie sich die Ausgabe ändert. Bei Stichprobenverfahren werden Stichproben aus einer Eingaberaumverteilung generiert und die Ausgabereaktion anhand der Eingabewerte berechnet. Zu den in DAKOTA verfügbaren Probenahmemethoden gehören Monte Carlo, Latin Hypercube und (in Kürze) Quasi-Monte Carlo. Bei der Versuchsplanung wird die Ausgabe an einer Reihe von Eingabe- "Entwurf" -Punkten bewertet, die ausgewählt wurden, um den Raum auf repräsentative Weise abzutasten. Das spezifische Design der in DAKOTA verfügbaren Versuchsmethoden umfasst Box-Behnken-, Central Composite- und Factorial-Designs. Sensitivitätsmetriken sind eine mathematische Methode, um die Abhängigkeit von Ausgaben von Eingaben auszudrücken. In Dakota stehen eine Vielzahl von Sensitivitätsmetriken zur Verfügung, z. B. einfache und partielle Korrelationskoeffizienten sowie Rangkorrelationen. Unsere aktuelle Forschung konzentriert sich auf Methoden zur Generierung von Sensitivitätsmetriken mit einer minimalen Anzahl von Läufen und auf die optimale Schätzung von Parametern in Computermodellen unter Verwendung von Bayes'schen Analysetechniken.

Aron Ahmadia
quelle
Ein weiteres Tool wie dieses ist SUSA, das von der GRS in Deutschland entwickelt wurde. Aber dieser ist nicht frei.
GertVdE
Das Problem bei Binärformaten ist, dass sie schwieriger zu warten sind. Es ist nicht ungewöhnlich, dass sich ein Dateiformat mit der Zeit entwickelt. Daher kann das Parsen und Unterstützen eines Binärformats ein Problem sein. Nach meiner Erfahrung funktionieren Klartext, Komprimierung (gzip) und ein bisschen Befehlszeile oder Python auch für ein paar hundert GB.
Fcruz
1
@fcruz ja, oder bzip2und 7zipdie noch bessere Komprimierungsraten für Text bieten.
Ajasja
8

Für meine Doktorarbeit stoße ich auf ähnliche Probleme wie Sie. Da ich jedoch nicht meinen Code verwende, bin ich nicht so flexibel wie Sie. Trotzdem habe ich ein paar Vorschläge.

Wie Pedro angedeutet hat, gibt es den Befehl tee. Wenn es jedoch nicht verfügbar ist oder Sie möchten, dass etwas in Ihre Software eingebaut wird, empfehle ich Ihnen, sich die boost::iostreamsBibliothek anzusehen. Es bietet Mechanismen zum Definieren von Eingabequellen und Ausgabe-Senken, die die Standardbibliothek nicht ausführt. Insbesondere gibt es das tee_device, mit dem Sie zwei Ausgabesenken an Ihren Stream anschließen können, und andere Streams können als Senken fungieren. Auf diese Weise können Sie die gleichzeitige Ausgabe in stdoutund eine Protokolldatei-Konfiguration abhängig machen.

boost::program_options1iniboost::program_optionsboost::property_tree

Um die Daten aus den verschiedenen Berechnungen zu erfassen, durchlaufe ich alle Datendateien, die ich in einen Satz aufnehmen möchte, und benutze dann awk , um eine einzelne Zeile in der Datei zu erzeugen und alle Ergebnisse in meine Ausgabe zu leiten. Dies kann einige Minuten dauern, aber ich habe leider keine bessere Methode.

In Bezug auf die Verarbeitung / Kommentierung Ihrer Daten kann ich die Nützlichkeit des Mathematica-Notizbuchformats nicht genug betonen. Es ermöglicht mir, meine Beobachtungen, Spekulationen und Visualisierungen an einem Ort zu organisieren. Meine Notebooks sind jedoch regelmäßig über 100 MB groß. Für eine gute Maßnahme, Mathematica führt ebenso wie Matlab auf Matrix Aufgaben. Darüber hinaus können Notizen mit vollständiger mathematischer Formatierung in Echtzeit erstellt werden.

Ich wünschte, ich hätte eine bessere Lösung für das Namensproblem, und es ist ziemlich schädlich. Aus diesem Grund kann es sich lohnen, einige Ihrer Daten in eine Datenbank auszugeben. Wenn Sie dies jedoch nicht möchten, sollten Sie erwägen, mithilfe der erweiterten Attribute in XFS umfassendere Informationen zu Ihrer Simulation zu erfassen und Ihre Konfigurationsdatei mit den Daten zu speichern, die zur Generierung verwendet wurden.

1. Als Beispiel für hierarchische Konfigurationsdateien untersuchte ein Freund von mir die Auswirkungen verschiedener Spitzengeometrien in AFM und jede Geometrie hatte einen anderen Parametersatz. Daneben testete er mehrere Berechnungsschemata, um sie mit Experimenten zu vergleichen, und sie hatten sehr unterschiedliche Parameter.

rcollyer
quelle
1
Was ich in letzter Zeit mache, ist, dass ich die Simulation von Mathematica aus steuere. Anstatt Konfigurationsdateien, Eingabedateien usw. zu verwenden und die Simulation zu einem Befehlszeilenprogramm zu machen, definiere ich einfach eine LibraryLink-Schnittstelle zu Mathematica. Auf diese Weise kann ich Parameter oder Daten strukturiert übergeben, und ich kann den Schmerz vermeiden, mit allen Arten von Befehlszeilenoptionen / Eingabe- / Ausgabe-Dateiformaten umgehen zu müssen. Ich erhalte sofortigen Zugriff auf Visualisierung / Plotten und kann das Ausführen der Simulation für verschiedene Parameter für komplexe Szenarien auf einfache Weise automatisieren.
Szabolcs
(So ​​komme ich mit dem adaptiven Sampling zurecht. Wenn ich mein Programm von der Kommandozeile aus aufrufe, ist das Implementieren von so etwas einfach zu viel Arbeit und zu viel Mühe, um ohne einen sehr guten Grund damit zu beginnen. Die Idee ist es nicht Die Verwendung eines High-Level-Systems wie Mathematica hat das Experimentieren so einfach gemacht, dass die Idee von selbst entstanden ist. Ich denke, man könnte andere High-Level-Systeme auf die gleiche Weise verwenden.)
Szabolcs
Vielen Dank für Ihre hilfreiche Antwort, ich werde einen Blick darauf werfen boost::property_tree. Ein weiteres Problem boost::program_optionsist, dass es als reine Headerbibliothek unbrauchbar zu sein scheint. Dies ist umständlich, wenn Sie möchten, dass Ihre Anwendung auf einem Computer ausgeführt wird, der nur Boost-Header enthält. Weiß übrigens jemand, warum das so ist? Anscheinend ist es sowieso eine recht kleine Bibliothek. (Vielleicht ist es besser, dies auf der Boost-Benutzerliste zu veröffentlichen)
Matija Kecman
@ mk527 Ich weiß nicht, was erforderlich ist, um das Erstellen boost::program_optionseiner Bibliothek zu erzwingen. Haben Sie sich jedoch das Dienstprogramm bcp zum Extrahieren einer Teilmenge von Boost angesehen?
rcollyer
3

Ich lerne PyTables bei der Installation von PETSC kennen. Und ich denke, die Tabellen- (oder Datenbank-) Methode eignet sich gut zum Erkunden des Parameterbereichs, obwohl ich es noch nicht ausprobiert habe. Wir können jeden Lauf mit spezifischen Parametern aufzeichnen und dann alle Aggregationen konsultieren, die bestimmte Bedingungen erfüllen, z. B. können wir dt und BDF1 korrigieren und alle relevanten Aufzeichnungen nachschlagen, um die Variation aufgrund der anderen Parameter zu untersuchen.

Ich würde gerne von Leuten hören, die tatsächlich die Tabellen- (oder Datenbank-) Methode zum Erkunden des Parameterraums verwenden. Ich freue mich über detaillierte Beispiele.

Hui Zhang
quelle
3

Das Durchsuchen des Parameterraums, wie Sie es versuchen, kann sehr schnell unhandlich werden. Es gibt so viele verschiedene Möglichkeiten, dies zu tun, dass es keine echte Lösung gibt.

Wenn Sie diese Grenze in Ihrer Arbeit erreichen, sollten Sie normalerweise die hierarchischen Datenformate HDF5 untersuchen . Mit HDF5 können Sie komplexe Ausgaben Ihrer Simulation in einem genau definierten Dateiformat speichern. Der Vorteil ist, dass Ihre Daten in einem einzigen, genau definierten Dateiformat gespeichert werden. Sie können Ihrer Datei mehrere Simulationsläufe hinzufügen, die durch verschiedene Parameter gekennzeichnet sind, und diese anschließend bearbeiten. Die Daten können komprimiert werden und lassen sich mit einer Vielzahl von Tools relativ einfach extrahieren. Es gibt einfach zu apis für C / C ++ / Python usw. und viele Befehlszeilen-Tools, um die Dateien zu bearbeiten. Ein Nachteil ist, dass das Schreiben in hdf5 nicht ganz so einfach ist wie das Schreiben in die Konsole. Bei HDF5-Beispielen gibt es viele Beispielprogramme .

tcb
quelle
2

Sie möchten eine indizierte Tabelle mit Variablenwerten führen. Der Index entspricht einem Ordner, in dem Sie die einzelnen Simulationseingaben und -ausgaben aufbewahren. Es handelt sich also nur um einen Index, und Sie müssen sich keine Gedanken über die Benennung von Konventionen oder Ordnerhierarchien machen, da Sie nachsehen, welche Parameterwerte den einzelnen Ordnern entsprechen.

Mit dieser Tabelle können Sie jetzt die Nachbearbeitung, das Plotten (Analysieren), das Protokollieren und das Kommentieren organisieren. Die Tabelle ist zentral für den Workflow.

Dies ist die Grundidee, und ich beschreibe, was Sie möglicherweise nur konzeptionell tun möchten. In meiner ersten Antwort schlug ich vor, das von mir entwickelte Framework zu untersuchen. In jüngerer Zeit habe ich Sumatra entdeckt . Es ist viel weiter entwickelt als mein individuell entwickelter, schwerfälliger Student und neu in der Python-Arbeit, aber ich denke, es versucht, zu viel zu tun. Es konzentriert sich auf Herkunftsinformationen, während sich mein Framework auf die Effizienz des Workflows konzentriert. Es gibt auch jobman , heilig und lencet .

Was auch immer Sie tun, ich empfehle Python nachdrücklich, um diese Art von Aufgaben zu bewältigen, da Sie Ihren gesamten Workflow mit Python verwalten können. Als kleine Geschichte habe ich gesehen, wie meine Kollegen mit DAKOTA, Bash, GNUplot, Dateinamenskonventionen, sed / awk - Oktaven usw. gearbeitet haben. ihre Rechenarbeit zu tun. Jedes dieser Tools ist für sich allein in Ordnung, aber die Leistungsfähigkeit von Python als integrierende Klebesprache ist wirklich hervorragend, wenn Sie Python für die Verwaltung Ihrer Arbeit zusammen mit dem wissenschaftlichen Stapel von Python verwenden. Ich hatte buchstäblich keine Probleme beim Verwalten meiner Computerarbeit, nachdem ich mein Framework entwickelt hatte.

/ Meine erste Antwort folgt /

Ich glaube, ich habe dieses Problem mit Python gelöst. Ich habe an all diese Probleme gedacht.

Überprüfen Sie mein Repo http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.html

Ab sofort arbeite ich jedoch daran, mein Framework besser zu dokumentieren. (Es ist mehr als das Ausfüllen einer Readme-Datei!)

-Majid alDosari

Majidaldosari
quelle
1
Hallo Majid, danke für den Beitrag und willkommen bei SciComp. Im Allgemeinen raten die StackExchange-Websites vom Verlinken auf externe Seiten ab und fordern zu detaillierten Antworten auf der Website selbst auf. Single-Link "Werbung" wird dringend abgeraten. Ich würde vorschlagen, diese Antwort zu überarbeiten oder zu löschen, da sie in der aktuellen Form wahrscheinlich nicht gut ankommt.
Aron Ahmadia
verstanden. Ich glaube einfach nicht, dass die Lösung in Form eines Posts gegeben werden kann. Das Problem ist recht allgemein.
Majidaldosari
1
Können Sie Ihre Herangehensweise an diese Probleme, an die Sie gedacht haben, zumindest zusammenfassen?
Christian Clason
1

Ich stimme der folgenden Implementierung zu, die ich im Verlauf meiner Ermittlungsarbeit entwickelt habe, wie sie hier , hier und hier zu finden ist .

Um Variablen an das Programm zu übergeben und dann ändern zu können, verwende ich das Paradigma der Verwendung eines Bash-Skripts, in dem ich definiere

export aValue=10
export bValue=2
export idName=test

und dann in C / C ++ verwenden

char *env_aValue = getenv("aValue");
char *env_bValue = getenv("bValue");
char *env_idName = getenv("idName");

aValue = atoi(env_aValue)
...

Der große Vorteil davon ist, dass:

  • es kann in einem globalen Bereich zugegriffen werden,
  • es ist tragbar für Sun Grid Engine (Cluster),
  • kann leicht über das Bash-Skript geändert werden,
  • es ist plattformunabhängig,
  • die Anzahl der Parameter kann sehr groß sein (möglicherweise unendlich)

Außerdem übergebe ich immer einen ID-Namen, auf dem jede von dieser ausführbaren Datei geschriebene Datei eine anfängliche Identifikation hat (auf Wunsch können andere Parameter folgen), und sie erhalten auch ein Exportverzeichnis = ID-Name, das auf der Datei erstellt wird Das Bash-Skript und alle Dateien dieser ausführbaren Datei werden darauf gespeichert. Auf diese Weise werden die Ergebnisse nach Verzeichnissen sortiert (optional).

Jorge Leitao
quelle
0

Sie können sfepy ausprobieren , ein Finite-Elemente-Programm, das fast vollständig in Python codiert ist. Es gibt auch ein Beispiel für ein Navier Stokes-Problem. Die Bedienung von sfepy ist sehr einfach.

Schattenkrieger
quelle
1
Ich habe nicht das Gefühl, dass diese Antwort die Frage beantwortet. Das Plakat hat eine Simulation; Ich habe den Eindruck, dass er ein Framework um seine vorhandene Simulation wickeln möchte, anstatt seine Simulation in einer anderen Software vollständig zu wiederholen.
Geoff Oxberry
sfepy funktioniert auch als Framework, man kann es als Black-Box-PDE-Solver verwenden. Aber ich denke, Sie haben Recht, da das Poster bereits viel Zeit für das Codieren aufgewendet hat.
Schattenkrieger
0

Haben Sie darüber nachgedacht, eine MySQL-Datenbank zu verwenden? Ich habe es noch nie gemacht, aber ich könnte mir vorstellen, dass man dieses System sehr gut abfragen kann! Vielleicht sind andere Systeme wie MongoDB besser. Das ist also nur eine Idee.

vanCompute
quelle