Qual è un buon modo per eseguire studi di parametri in C ++


29

Il problema

Attualmente sto lavorando a una simulazione di Navier Stokes agli elementi finiti e vorrei studiare gli effetti di una varietà di parametri. Alcuni parametri sono specificati in un file di input o tramite le opzioni della riga di comando; altri parametri sono forniti come flag in un Makefile, quindi il mio codice deve essere ricompilato ogni volta che cambio quelle opzioni. Sarei interessato a ricevere qualche consiglio su un buon modo per esplorare sistematicamente lo spazio dei parametri.

  • Ci sono utili librerie / framework C ++ / Python che possono aiutare in questo genere di cose? Ad esempio, scoprire boost.Program_options è stato di grande aiuto poiché è possibile sovraccaricare le opzioni del file di input con argomenti della riga di comando. Ho anche visto alcune persone usare un file di lavoro che descrive ogni caso in modo abbastanza efficace e un collega ha suggerito che scrivere parametri in file vtu come blocchi di commenti potrebbe funzionare anche.
  • Forse non vale la pena investire molto tempo in questo? È solo una distrazione e una perdita di tempo ed è meglio solo muscolare attraverso il processo di test forza bruta e ad hoc?

Alcuni pensieri

Attualmente sto facendo le cose principalmente a mano e ho riscontrato i seguenti problemi:

  • Casi di test di denominazione . Ho provato a memorizzare i risultati in cartelle denominate con i parametri di esecuzione separati da caratteri di sottolineatura, ad es Re100_dt02_BDF1.... Questi diventano rapidamente lunghi o difficili da leggere / criptici se vengono abbreviati troppo. Inoltre, i parametri dei numeri reali includono un .che è scomodo / brutto.
  • Registrazione dei dati di esecuzione . A volte vorrei vedere i risultati scritti sul terminale e salvati anche in un file di testo. Questa risposta di StackOverflow, ad esempio, è in qualche modo utile, ma le soluzioni sembrano essere un po 'invadenti.
  • Stampa dei dati in base al parametro . Ci vuole un po 'di tempo a raccogliere dati rilevanti da una varietà di file di registro in un singolo file che posso quindi tracciare, con un sistema migliore forse questo sarebbe più facile.
  • Registrazione dei commenti sui dati . Dopo aver esaminato i risultati, scrivo alcuni commenti in un file di testo, ma mantenere questo è sincronizzato con le cartelle dei risultati a volte è difficile.

Molto dipende da cosa intendi per "esplorare". Indica i tuoi obiettivi in ​​modo più preciso.
Arnold Neumaier,

Risposte:


10

Solo alcuni commenti su due dei tuoi punti:

  • Registrazione dei dati di esecuzione : la soluzione migliore è probabilmente il piping dell'output tramite il comando tee , che dovrebbe essere disponibile nella maggior parte delle shell.

  • Tracciare i dati in base al parametro : suppongo sia una questione di gusti, ma quando devo fare complesse aggregazioni di dati, memorizzo i risultati in testo semplice, li leggo in Matlab come matrici e faccio tutti i calcoli, la stampa e persino l'output di LaTeX da li. Ovviamente, qualunque sia il linguaggio di programmazione / scripting che hai più familiarità ti darà i migliori risultati.


Grazie, il teecomando è molto utile
Matija Kecman,

11

Se vuoi scrivere qualcosa per scopi generici, puoi farlo con gli script di shell se è qualcosa di molto semplice, come suggerisce Pedro , o aggregare in un linguaggio di programmazione matematica di livello superiore come Python o MATLAB. Concordo sul fatto che i file di testo semplice siano utili per piccole quantità di dati, ma probabilmente dovresti passare ai dati binari per qualcosa di più grande di qualche megabyte.

D'altra parte, se stai solo facendo una stima dei parametri, ti consiglierei di utilizzare un software specificamente adatto a questo. Diversi ricercatori della mia Università hanno avuto fortuna con DAKOTA , una cassetta degli attrezzi per la quantificazione dell'incertezza dei Sandia National Laboratories ( disponibile con una GNU Lesser General Public License ).

Ecco un estratto dalla pagina di Sandia che descrive DAKOTA:

Offriamo una varietà di metodi per consentire a un utente di eseguire una raccolta di simulazioni al computer per valutare la sensibilità degli output del modello rispetto agli input del modello. Le categorie comuni includono studi di parametri, metodi di campionamento e progettazione di esperimenti. Negli studi sui parametri si fa passare alcuni parametri di input attraverso un intervallo mantenendo fissi altri parametri di input e si valuta come varia l'output. Nei metodi di campionamento, si generano campioni da una distribuzione dello spazio di input e si calcola la risposta di output ai valori di input. Metodi di campionamento specifici disponibili all'interno di DAKOTA includono Monte Carlo, Hypercube latino e (in arrivo) quasi-Monte Carlo. Nella progettazione di esperimenti l'output viene valutato in una serie di punti di "progettazione" di input scelti per campionare lo spazio in modo rappresentativo. La progettazione specifica dei metodi di esperimento disponibili all'interno di DAKOTA include progetti Box-Behnken, Central Composite e Factorial. Le metriche di sensibilità sono un modo matematico per esprimere la dipendenza degli output dagli input. All'interno del Dakota sono disponibili diverse metriche di sensibilità, come coefficienti di correlazione semplici e parziali e correlazioni di rango. La nostra ricerca attuale si concentra sui metodi per generare metriche di sensibilità con un numero minimo di esecuzioni e sulla stima ottimale dei parametri nei modelli di computer utilizzando tecniche di analisi bayesiane.


Un altro strumento come questo è SUSA sviluppato da GRS in Germania. Ma questo non è gratuito.
GertVdE,

Il problema con i formati binari è che sono più difficili da mantenere, non è raro che un formato file si evolva nel tempo, quindi l'analisi e il supporto di un formato binario possono essere una seccatura. Nella mia esperienza, il testo semplice, la compressione (gzip) e un po 'di riga di comando o python per cucire insieme funzionano bene anche per poche centinaia di GB.
fcruz,

1
@fcruz sì, o bzip2e 7zipche offrono anche migliori rapporti di compressione per il testo.
Ajasja

8

Per il mio lavoro di dottorato, mi imbatto in problemi simili come te. Dal momento che non sto usando il mio codice, non ho la stessa flessibilità di te. Detto questo, ho alcuni suggerimenti.

Come ha suggerito Pedro, c'è il comando tee. Ma, se non è disponibile, o desideri qualcosa integrato nel tuo software stesso, ti suggerisco di guardare la boost::iostreamslibreria. Fornisce meccanismi per la definizione delle origini di input e dei sink di output che la libreria standard non esegue. In particolare, c'è quello tee_deviceche ti permette di connettere due sink di output al tuo stream e altri stream possono agire come sink. Ciò consentirebbe di rendere stdoutdipendente l'output simultaneo e la configurazione di un file di registro.

boost::program_options1iniboost::program_optionsboost::property_tree e di salvare gli alberi per riutilizzarli in seguito. Ciò ha l'ulteriore vantaggio che se è necessario verificare il codice, è possibile salvare lo stato corrente come input al riavvio.

Per raccogliere i dati dai diversi calcoli, eseguo il ciclo su tutti i file di dati che vorrei includere in un set, quindi uso awk per produrre una singola riga nel file e installo tutti i risultati nel mio output. Questo può richiedere un paio di minuti, ma sfortunatamente non ho un metodo migliore.

Per quanto riguarda l'elaborazione / i commenti sui tuoi dati, non posso sottolineare abbastanza l'utilità del formato del notebook Mathematica. Mi permette di organizzare le mie osservazioni, speculazioni e visualizzazioni in un unico posto. Tuttavia, i miei notebook superano regolarmente i 100 MB. Per una buona misura, Mathematica esegue altrettanto bene come Matlab su compiti di matrice. Inoltre, può essere utilizzato per prendere appunti con la formattazione matematica completa in tempo reale.

Vorrei avere una soluzione migliore al problema dei nomi, ed è piuttosto pernicioso. Potrebbe essere utile considerare la possibilità di inviare alcuni dei tuoi dati in un database per questo motivo. Tuttavia, se non si desidera farlo, prendere in considerazione l'utilizzo degli attributi estesi in XFS per acquisire informazioni più complete sulla simulazione e archiviare il file di configurazione con i dati utilizzati per la generazione.

1. Come esempio in cui sono necessari file di configurazione gerarchici, un mio amico stava esaminando gli effetti di diverse geometrie di punta in AFM e ciascuna geometria aveva un diverso set di parametri. Inoltre, oltre a questo, stava testando diversi schemi di calcolo in modo da poterli confrontare per sperimentare e avevano parametri molto diversi.


1
Quello che faccio di recente è che guido la simulazione da Mathematica. Invece di utilizzare file di configurazione, file di input, ecc. E rendere la simulazione un programma da riga di comando, definisco semplicemente un'interfaccia LibraryLink per Mathematica. In questo modo posso passare parametri o dati in modo strutturato e posso evitare il dolore di dover gestire ogni sorta di opzioni da riga di comando / formati di file input-output. Ho accesso immediato alla visualizzazione / stampa e posso facilmente automatizzare l'esecuzione della simulazione per diversi parametri per scenari complessi.
Szabolcs,

(Questo è il modo in cui mi avvicino alla cosa del campionamento adattivo . Se stavo chiamando il mio programma dalla riga di comando, l'implementazione di qualcosa del genere è troppo lavoro e troppi problemi per iniziare a fare senza una ragione molto buona. L'idea non è probabilmente uscirà dalla pura sperimentazione. L'uso di un sistema di alto livello come Mathematica ha reso la sperimentazione abbastanza semplice da rendere l'idea naturale. Immagino che si possano usare altri sistemi di alto livello allo stesso modo.)
Szabolcs,

Grazie per la tua risposta utile, darò un'occhiata boost::property_tree. Un altro problema boost::program_optionsè che sembra essere inutilizzabile come libreria solo intestazione, il che è imbarazzante se si desidera che l'applicazione venga eseguita su un computer che ha solo il potenziamento delle intestazioni. Per inciso, qualcuno sa perché questo è? Apparentemente è comunque una piccola biblioteca. (Forse è meglio pubblicarlo nell'elenco degli utenti boost)
Matija Kecman,

@ mk527 Non so cosa sia richiesto boost::program_optionsper forzarlo a trasformarlo in una libreria. Tuttavia, hai guardato l' utilità bcp per l'estrazione di un sottoinsieme di boost?
rcollyer,

3

Conosco PyTables durante l'installazione di PETSC. E immagino che il metodo table (o database) sia adatto per esplorare lo spazio dei parametri, anche se non ho ancora provato. Possiamo registrare ogni corsa con parametri specifici e quindi possiamo consultare qualsiasi aggregazione che soddisfi alcune condizioni, diciamo, possiamo correggere dt, BDF1 e cercare tutti i record rilevanti per studiare la variazione dovuta agli altri parametri.

Mi piacerebbe conoscere le persone che stanno effettivamente utilizzando il metodo table (o database) per esplorare lo spazio dei parametri. Apprezzerò per esempi dettagliati.


3

Esplorare lo spazio dei parametri come si sta tentando di fare può diventare molto rapidamente ingombrante. Ci sono così tanti modi diversi per farlo che non esiste una vera soluzione.

Di solito quando raggiungi questo limite nel tuo lavoro, potresti voler esaminare i formati di dati gerarchici HDF5 . HDF5 consente di archiviare output complessi della simulazione in un formato file ben definito. I vantaggi sono che i tuoi dati sono archiviati in un unico formato di file ben definito. È possibile aggiungere più file di simulazione, identificati da parametri diversi, al file e successivamente manipolarli. I dati possono essere compressi ed è abbastanza facile da estrarre utilizzando una varietà di strumenti. Ci sono facili apis per c / c ++ / python ecc. E molti strumenti da riga di comando per manipolare i file. Uno svantaggio è che scrivere su hdf5 non è così semplice come scrivere sulla console. Ci sono molti programmi di esempio negli esempi HDF5 .


2

Si desidera mantenere una tabella indicizzata di valori variabili. L'indice corrisponde a una cartella in cui si mantengono input e output di ciascuna simulazione. Quindi è solo un indice e non devi preoccuparti della convenzione di denominazione o delle gerarchie di cartelle perché cercherai quali valori dei parametri corrispondono a ciascuna cartella.

Quindi ora puoi utilizzare questa tabella per organizzare la post-elaborazione, la stampa (analisi), la registrazione e i commenti. La tabella è centrale nel flusso di lavoro.

Questa è l'idea di base e sto descrivendo cosa potresti voler fare solo concettualmente. Nella mia risposta iniziale, ho suggerito di esaminare il framework che ho sviluppato. Più recentemente ho scoperto Sumatra . È molto più sviluppato del mio studente laureato sviluppato individualmente e in difficoltà e nuovo allo sforzo di Python, ma penso che cerchi di fare troppo. Si concentra sulle informazioni sulla provenienza mentre il mio framework si concentra sull'efficienza del flusso di lavoro. C'è anche jobman , sacred e lencet .

Qualunque cosa tu scelga di fare, consiglio vivamente a Python di affrontare questi tipi di attività poiché puoi gestire l'intero flusso di lavoro con Python. Proprio come una piccola storia, ho visto i miei colleghi lavorare con DAKOTA, bash, GNUplot, convenzioni di denominazione dei file, ottava sed / awk ... ecc. per fare il loro lavoro computazionale. Ognuno di questi strumenti va bene per conto proprio, ma la potenza di Python come linguaggio di colla integrato brilla davvero quando usi Python per gestire il tuo lavoro insieme allo stack scientifico di Python. Ho letteralmente avuto zero problemi a gestire il mio lavoro computazionale dopo aver sviluppato il mio framework.

/ segue la mia risposta iniziale /

Credo di aver risolto questo problema usando Python. Ho pensato a tutti questi problemi.

Dai un'occhiata al mio repository http://msdresearch.blogspot.com/2012/01/parameter-study-management-with-python.html

Per ora, sto lavorando per documentare meglio il mio framework. (è più complicato che compilare un file Leggimi!)

-Majid alDosari


1
Ciao Majid, grazie per il contributo e benvenuto in SciComp. In generale, i siti StackExchange scoraggiano il collegamento a pagine esterne e incoraggiano risposte dettagliate sul sito stesso. Gli "annunci pubblicitari" a collegamento singolo sono fortemente scoraggiati. Suggerirei di rivedere o eliminare questa risposta, poiché probabilmente non verrà ricevuta bene nella sua forma attuale.
Aron Ahmadia,

inteso. semplicemente non credo che la soluzione possa essere data sotto forma di un post. il problema è abbastanza generale.
majidaldosari,

1
Potresti almeno riassumere il tuo approccio a questi problemi a cui hai pensato?
Christian Clason,

1

Tendo a concordare nella seguente implementazione, che ho sviluppato nel corso del mio lavoro di indagine, come si può trovare qui , qui e qui .

Per passare le variabili al programma ed essere in grado di cambiare, utilizzo il paradigma dell'uso di uno script bash in cui definisco

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

e quindi utilizzare in C / C ++

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

aValue = atoi(env_aValue)
...

I grandi vantaggi di questo è che:

  • è possibile accedervi in ​​un ambito globale,
  • è portatile per il motore a griglia solare (cluster),
  • può essere facilmente modificato sullo script bash,
  • è indipendente dalla piattaforma,
  • il numero di parametri può essere molto grande (potenzialmente infinito)

Inoltre, passo sempre un idName, sul quale ogni file scritto da quel file eseguibile avrà una sua identificazione iniziale (può essere seguito da altri parametri se vuoi), e ricevono anche una directory di esportazione = idName, che viene creata sul bash script e tutti i file di quel file eseguibile vengono salvati su di esso. In questo modo i risultati sono organizzati per directory (facoltativo).


0

Puoi dare un'occhiata a sfepy che è un programma ad elementi finiti quasi interamente codificato in Python. Ha anche un problema di esempio con Navier Stokes. La procedura operativa di sfepy è molto semplice.


1
Non mi sembra che questa risposta risponda alla domanda. Il poster ha una simulazione; Ho l'impressione che voglia avvolgere un framework attorno alla sua simulazione esistente, piuttosto che rifare completamente la sua simulazione in diversi software.
Geoff Oxberry,

sfepy funziona anche come framework, è possibile utilizzarlo come solutore PDE black box. Ma penso che tu abbia ragione, visto che il poster ha già dedicato molto tempo alla programmazione.
ShadowWarrior,

0

Hai pensato di utilizzare un database MySQL? Non l'ho mai fatto, ma potrei immaginare che puoi interrogare questo sistema molto bene! Forse altri sistemi come MongoDB sono migliori. Quindi, questa è solo un'idea.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.