Quelle est la bonne façon d'exécuter des études de paramètres en C ++


29

Le problème

Je travaille actuellement sur une simulation d'élément fini Navier Stokes et j'aimerais étudier les effets d'une variété de paramètres. Certains paramètres sont spécifiés dans un fichier d'entrée ou via une option de ligne de commande; d'autres paramètres sont fournis sous forme d'indicateurs dans un Makefile, mon code doit donc être recompilé chaque fois que je modifie ces options. Je serais intéressé à obtenir des conseils sur une bonne façon d'explorer systématiquement l'espace des paramètres.

  • Existe-t-il des bibliothèques / frameworks C ++ / Python utiles qui peuvent aider avec ce genre de choses? Par exemple, découvrir boost.Program_options a été d'une grande aide car il est possible de surcharger les options du fichier d'entrée avec des arguments de ligne de commande. J'ai également vu certaines personnes utiliser un fichier de travail décrivant chaque cas assez efficacement et un collègue a suggéré que l'écriture de paramètres dans des fichiers vtu sous forme de blocs de commentaires pourrait également fonctionner.
  • Peut-être que cela ne vaut pas la peine d'investir beaucoup de temps dans tout cela? Est-ce juste une distraction et une perte de temps et il est préférable de se muscler à travers le processus de test par force brute et ad hoc?

Quelques idées

Je fais actuellement des choses principalement à la main et j'ai rencontré les problèmes suivants:

  • Nommer les cas de test . J'ai essayé de stocker les résultats dans des dossiers nommés avec les paramètres d'exécution séparés par des traits de soulignement, par exemple Re100_dt02_BDF1.... Celles-ci deviennent rapidement longues ou difficiles à lire / cryptiques si elles sont trop abrégées. En outre, les paramètres de nombre réel incluent un .qui est maladroit / laid.
  • Journalisation des données d'exécution . Parfois, j'aimerais voir les résultats écrits sur le terminal et également enregistrés dans un fichier texte. Cette réponse de StackOverflow par exemple est quelque peu utile mais les solutions semblent un peu intrusives.
  • Tracer les données selon les paramètres . Il faut un certain temps pour collecter des données pertinentes à partir d'une variété de fichiers journaux dans un seul fichier que je peux ensuite tracer, avec un meilleur système, cela deviendrait peut-être plus facile.
  • Enregistrement des commentaires sur les données . Après avoir examiné les résultats, j'écris quelques commentaires dans un fichier texte, mais garder cette synchronisation avec les dossiers de résultats est parfois difficile.

Cela dépend beaucoup de ce que vous entendez par «explorer». Veuillez préciser vos objectifs.
Arnold Neumaier

Réponses:


10

Quelques commentaires sur deux de vos points:

  • Journalisation des données d'exécution : votre meilleur pari est probablement la sortie de la tuyauterie via la commande tee , qui devrait être disponible dans la plupart des shells.

  • Tracer des données en fonction de paramètres : je suppose que c'est une question de goût, mais quand je dois faire une agrégation de données complexe, je stocke les résultats en texte brut, les lis dans Matlab en tant que matrices, et fais tous les calculs, le traçage et même la sortie LaTeX De là. Évidemment, quel que soit le langage de programmation / script que vous connaissez le mieux, vous obtiendrez les meilleurs résultats.


Merci, la teecommande est très utile
Matija Kecman

11

Si vous voulez écrire quelque chose à usage général, vous pouvez le faire avec des scripts shell si c'est quelque chose de très simple, comme le suggère Pedro , ou l'agréger dans un langage de programmation mathématique de niveau supérieur tel que Python ou MATLAB. Je suis d'accord que les fichiers en texte brut sont utiles pour de plus petites quantités de données, mais vous devriez probablement passer aux données binaires pour quelque chose de plus grand que quelques mégaoctets.

D'un autre côté, si vous faites juste une estimation de paramètres, je recommanderais d'utiliser un logiciel spécialement adapté à cela. Plusieurs chercheurs de mon université ont eu de la chance avec DAKOTA , une boîte à outils de quantification d'incertitude des Sandia National Laboratories ( disponible sous une licence GNU Lesser General Public License ).

Voici un extrait de la page Sandia décrivant DAKOTA:

Nous fournissons une variété de méthodes pour permettre à un utilisateur d'exécuter une collection de simulations informatiques pour évaluer la sensibilité des sorties du modèle par rapport aux entrées du modèle. Les catégories communes comprennent les études de paramètres, les méthodes d'échantillonnage et la conception des expériences. Dans les études de paramètres, on fait passer certains paramètres d'entrée dans une plage tout en gardant les autres paramètres d'entrée fixes et on évalue la variation de la sortie. Dans les méthodes d'échantillonnage, on génère des échantillons à partir d'une distribution d'espace d'entrée et calcule la réponse de sortie aux valeurs d'entrée. Les méthodes d'échantillonnage spécifiques disponibles au sein de DAKOTA comprennent Monte Carlo, l'hypercube latin et (à venir) quasi-Monte Carlo. Dans la conception des expériences, la sortie est évaluée à un ensemble de points de «conception» d'entrée choisis pour échantillonner l'espace de manière représentative. La conception spécifique des méthodes d'expérimentation disponibles dans DAKOTA comprend les conceptions Box-Behnken, Central Composite et Factorial. Les métriques de sensibilité sont une manière mathématique d'exprimer la dépendance des sorties par rapport aux entrées. Une variété de mesures de sensibilité sont disponibles dans Dakota, telles que des coefficients de corrélation simples et partiels et des corrélations de rang. Nos recherches actuelles se concentrent sur les méthodes permettant de générer des mesures de sensibilité avec un nombre minimal d'exécutions et sur une estimation optimale des paramètres dans les modèles informatiques utilisant des techniques d'analyse bayésienne.


Un autre outil comme celui-ci est SUSA développé par GRS en Allemagne. Mais celui-ci n'est pas gratuit.
GertVdE

Le problème avec les formats binaires est qu'ils sont plus difficiles à maintenir, il n'est pas rare qu'un format de fichier évolue avec le temps, donc l'analyse et la prise en charge d'un format binaire peuvent être pénibles. D'après mon expérience, le texte brut, la compression (gzip) et un peu de ligne de commande ou de python pour assembler tous fonctionnent bien, même pour quelques centaines de Go.
fcruz

1
@fcruz yes, ou bzip2et 7zipqui offrent des taux de compression encore meilleurs pour le texte.
Ajasja

8

Pour mon travail de doctorat, je rencontre des problèmes similaires à vous. Comme ce n'est pas mon code que j'utilise, je n'ai pas tout à fait la même flexibilité que vous. Cela dit, j'ai quelques suggestions.

Comme l'a suggéré Pedro, il y a la commande tee. Mais, s'il n'est pas disponible, ou si vous souhaitez que quelque chose soit intégré à votre logiciel lui-même, je vous suggère de consulter la boost::iostreamsbibliothèque. Il fournit des mécanismes pour définir les sources d'entrée et les récepteurs de sortie que la bibliothèque standard ne fait pas. En particulier, il y a le tee_devicequi vous permet de connecter deux récepteurs de sortie à votre flux, et d' autres flux peuvent agir comme des récepteurs. Cela vous permettrait de rendre la sortie simultanée vers stdoutet une configuration de fichier journal dépendante.

Je reconnais que cela boost::program_optionspeut être très utile pour configurer votre logiciel. Cependant, il a quelques défauts qui peuvent avoir un impact sur la façon dont vous faites les choses. Premièrement, si vous avez besoin d'une configuration hiérarchique, alors les fichiers sont un moyen douloureux de l'accomplir. Deuxièmement, et plus important encore, n'a aucune capacité de sortie, vous ne pouvez donc pas enregistrer votre état en tant que fichier de configuration pour une inspection ultérieure ou la reprise d'un code arrêté. Comme alternative, je suggère d' utiliser qui prend en charge la configuration hiérarchique des fichiers et la sauvegarde des arbres pour une réutilisation ultérieure. Cela a l'avantage supplémentaire que si vous devez vérifier votre code, vous pouvez enregistrer son état actuel en entrée lorsque vous redémarrez.1iniboost::program_optionsboost::property_tree

Pour rassembler les données des différents calculs, je fais une boucle sur tous les fichiers de données que j'aimerais inclure dans un ensemble, j'utilise ensuite awk pour produire une seule ligne dans le fichier et je dirige tous les résultats dans ma sortie. Cela peut prendre quelques minutes, mais malheureusement, je n'ai pas de meilleure méthode.

Quant au traitement / commentaire de vos données, je ne saurais trop insister sur l'utilité du format de cahier Mathematica. Cela me permet d'organiser mes observations, spéculations et visualisations en un seul endroit. Cependant, mes ordinateurs portables dépassent régulièrement les 100 Mo. Pour faire bonne mesure, Mathematica fonctionne aussi bien que Matlab sur les tâches matricielles. De plus, il peut être utilisé pour prendre des notes avec une mise en forme mathématique complète en temps réel.

J'aimerais avoir une meilleure solution au problème de nommage, et c'est plutôt pernicieux. Pour cette raison, il peut être utile d'envisager la sortie de certaines de vos données dans une base de données. Cependant, si vous ne le souhaitez pas, envisagez d'utiliser les attributs étendus dans XFS pour capturer des informations plus complètes sur votre simulation et stockez votre fichier de configuration avec les données qu'il a été utilisé pour générer.

1. À titre d'exemple où des fichiers de configuration hiérarchiques sont nécessaires, un de mes amis examinait les effets de différentes géométries de pointe dans AFM et chaque géométrie avait un ensemble de paramètres différent. En plus de cela, il testait plusieurs schémas de calcul afin de pouvoir les comparer à l'expérimentation, et ils avaient des paramètres très différents.


1
Ce que je fais récemment, c'est que je pilote la simulation à partir de Mathematica. Au lieu d'utiliser des fichiers de configuration, des fichiers d'entrée, etc. et de faire de la simulation un programme en ligne de commande, je définis simplement une interface LibraryLink pour Mathematica. De cette façon, je peux transmettre des paramètres ou des données de manière structurée, et je peux éviter la douleur d'avoir à gérer toutes sortes d'options de ligne de commande / formats de fichier d'entrée-sortie. J'ai un accès instantané à la visualisation / au traçage et je peux facilement automatiser l'exécution de la simulation pour différents paramètres pour des scénarios complexes.
Szabolcs

(C'est ainsi que je me présente avec l' échantillonnage adaptatif . Si j'appelais mon programme à partir de la ligne de commande, implémenter quelque chose comme ça est tout simplement trop de travail et trop de mal à commencer à le faire sans une très bonne raison. L'idée n'est pas susceptibles de sortir de l'expérimentation pure. L'utilisation d'un système de haut niveau comme Mathematica a rendu l'expérimentation assez facile pour que l'idée vienne naturellement. Je suppose que l'on pourrait utiliser d'autres systèmes de haut niveau de la même manière.)
Szabolcs

Merci pour votre réponse utile, je vais y jeter un œil boost::property_tree. Un autre problème boost::program_optionsest qu'elle semble inutilisable en tant que bibliothèque d'en-tête uniquement, ce qui est gênant si vous souhaitez que votre application s'exécute sur une machine qui n'a que des en-têtes boost. Soit dit en passant, quelqu'un sait-il pourquoi c'est le cas? Apparemment, c'est une toute petite bibliothèque de toute façon. (Peut-être vaut-il mieux l'afficher sur la liste des utilisateurs boostés)
Matija Kecman

@ mk527 Je ne sais pas ce qui est requis boost::program_optionspour le forcer à être transformé en bibliothèque. Cependant, avez-vous regardé l' utilitaire bcp pour extraire un sous-ensemble de boost?
rcollyer

3

Je découvre PyTables lors de l'installation de PETSC. Et je suppose que la méthode de la table (ou de la base de données) est bien adaptée pour explorer l'espace des paramètres, même si je n'ai pas encore essayé. Nous pouvons enregistrer chaque exécution avec des paramètres spécifiques, puis nous pouvons consulter toutes les agrégations satisfaisant à certaines conditions, par exemple, nous pouvons fixer dt, BDF1 et rechercher tous les enregistrements pertinents pour étudier la variation due aux autres paramètres.

J'aimerais entendre des personnes qui utilisent réellement la méthode de table (ou de base de données) pour explorer l'espace des paramètres. J'apprécierai pour des exemples détaillés.


3

Explorer l'espace des paramètres comme vous essayez de le faire peut devenir très rapidement difficile à manier. Il y a tellement de façons différentes de faire cela qu'il n'y a pas de vraie solution.

Habituellement, lorsque vous atteignez cette limite dans votre travail, vous souhaiterez peut-être étudier les formats de données hiérarchiques HDF5 . HDF5 vous permet de stocker une sortie complexe de votre simulation dans un format de fichier bien défini. Les avantages sont que vos données sont stockées dans un seul format de fichier bien défini. Vous pouvez ajouter plusieurs exécutions de simulation, identifiées par différents paramètres, à votre fichier et les manipuler ensuite. Les données peuvent être compressées et sont assez faciles à extraire à l'aide d'une variété d'outils. Il existe des API faciles à utiliser pour c / c ++ / python, etc. et de nombreux outils en ligne de commande pour manipuler les fichiers. Un inconvénient est que l'écriture sur hdf5 n'est pas aussi simple que l'écriture sur la console. Il existe de nombreux programmes d'exemple dans les exemples HDF5 .


2

Vous souhaitez conserver une table indexée de valeurs variables. L'index correspond à un dossier dans lequel vous conservez chaque entrée et sortie de simulation. Il ne s'agit donc que d'un index et vous n'avez pas à vous soucier des conventions de dénomination ou des hiérarchies de dossiers, car vous rechercherez les valeurs des paramètres correspondant à chaque dossier.

Alors maintenant, vous pouvez utiliser ce tableau pour organiser votre post-traitement, le traçage (analyse), la journalisation et les commentaires. Le tableau est au cœur du workflow.

C'est l'idée de base, et je décris ce que vous voudrez peut-être faire uniquement conceptuellement. Dans ma réponse initiale, j'ai suggéré d'examiner le cadre que j'ai développé. Plus récemment, j'ai découvert Sumatra . Il est beaucoup plus développé que mon étudiant diplômé en difficulté, développé individuellement, et nouveau dans l'effort de python, mais je pense qu'il essaie d'en faire trop. Il se concentre sur les informations de provenance tandis que mon cadre se concentre sur l'efficacité du flux de travail. Il y a aussi jobman , sacré et lencet .

Quoi que vous choisissiez de faire, je recommande fortement à python de s'attaquer à ce type de tâches, car vous pouvez gérer l'ensemble de votre flux de travail avec python. Juste pour une petite histoire, j'ai regardé mes collègues travailler avec DAKOTA, bash, GNUplot, les conventions de dénomination des fichiers, l'octave sed / awk ... etc. pour faire leur travail de calcul. Chacun de ces outils est bien en soi, mais la puissance de python en tant que langage de collage intégrateur brille vraiment lorsque vous utilisez python pour gérer votre travail avec la pile scientifique python. Je n'ai littéralement eu aucun problème à gérer mon travail de calcul après avoir développé mon framework.

/ ma réponse initiale suit /

Je crois avoir résolu ce problème en utilisant python. J'ai pensé à toutes ces questions.

Consultez mon référentiel http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.html

Pour l'instant cependant, je travaille sur une meilleure documentation de mon framework. (c'est plus compliqué que de remplir un readme!)

-Majid alDosari


1
Salut Majid, merci pour la contribution et bienvenue à SciComp. En général, les sites StackExchange découragent les liens vers des pages externes et encouragent des réponses détaillées sur le site lui-même. Les "publicités" à lien unique sont fortement déconseillées. Je suggère de réviser ou de supprimer cette réponse, car elle ne sera probablement pas bien reçue dans sa forme actuelle.
Aron Ahmadia

compris. Je ne crois tout simplement pas que la solution puisse être donnée sous la forme d'un message. le problème est assez général.
majidaldosari

1
Pourriez-vous au moins résumer votre approche de ces questions auxquelles vous avez pensé?
Christian Clason

1

J'ai tendance à être d'accord sur la mise en œuvre suivante, que j'ai développée au cours de mon travail d'enquête, comme on peut le trouver ici , ici et ici .

Pour passer des variables au programme et pouvoir ensuite les changer, j'utilise le paradigme d'utilisation d'un script bash où je définis

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

puis utiliser en C / C ++

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

aValue = atoi(env_aValue)
...

Les grands avantages de ceci sont que:

  • il est accessible à l'échelle mondiale,
  • il est portable au moteur de grille solaire (clusters),
  • peut être facilement modifié sur le script bash,
  • il est indépendant de la plateforme,
  • le nombre de paramètres peut être très important (potentiellement infini)

En outre, je passe toujours un idName, sur lequel chaque fichier écrit par cet exécutable aura une identification initiale de celui-ci (peut être suivi par d'autres paramètres si vous le souhaitez), et ils reçoivent également un répertoire d'exportation = idName, qui est créé sur le script bash, et tous les fichiers de cet exécutable y sont enregistrés. De cette façon, les résultats sont organisés par répertoires (facultatif).


0

Vous pouvez consulter sfepy qui est un programme d'éléments finis presque entièrement codé en python. Il a également un exemple de problème Navier Stokes. La procédure de fonctionnement de sfepy est très simple.


1
Je n'ai pas l'impression que cette réponse réponde à la question. L'affiche a une simulation; J'ai l'impression qu'il veut envelopper un cadre autour de sa simulation existante, plutôt que de refaire complètement sa simulation dans différents logiciels.
Geoff Oxberry

sfepy fonctionne aussi comme un framework, on peut l'utiliser comme un solveur PDE de boîte noire. Mais je pense que vous avez raison, car l'affiche a déjà consacré beaucoup de temps au codage.
ShadowWarrior

0

Avez-vous pensé à utiliser une base de données MySQL? Je ne l'ai jamais fait, mais je pourrais imaginer que vous pouvez interroger ce système très bien! Peut-être que d'autres systèmes comme MongoDB sont meilleurs. Donc, ce n'est qu'une idée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.